diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-02-22 13:35:51 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-02-22 13:35:51 -0800 |
commit | 6861eaf79155f0a5544ff989754159f806795c31 (patch) | |
tree | 99f6b7c2ceebced94075ca5e54f5dff09ff7bd4b /include | |
parent | f0b2769a0185ccf84842a795b5587afc37274c3d (diff) | |
parent | 8844f0aa8dc42f54dc278c8d4ecbf32e92f2d6f1 (diff) | |
download | lwn-6861eaf79155f0a5544ff989754159f806795c31.tar.gz lwn-6861eaf79155f0a5544ff989754159f806795c31.zip |
Merge tag 'ata-6.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/libata
Pull ATA updates from Damien Le Moal:
- Small cleanup of the pata_octeon driver to drop a useless platform
callback (Uwe)
- Simplify ata_scsi_cmd_error_handler() code using the fact that
ap->ops->error_handler is NULL most of the time (Wenchao)
- Several patches improving libata error handling. This is in
preparation for supporting the command duration limits (CDL) feature.
The changes allow handling corner cases of ATA NCQ errors which do
not happen with regular drives but will be triggered with CDL drives
(Niklas)
- Simplify the qc_fill_rtf operation (me)
- Improve SCSI command translation for REPORT_SUPPORTED_OPERATION_CODES
command (me)
- Cleanup of libata FUA handling.
This falls short of enabling FUA for ATA drives that support it by
default as there were concerns that old drives would break. The
series however fixes several issues with the FUA support to ensure
that FUA is reported as being supported only for drives that can
handle all possible write cases (NCQ and non-NCQ). A check in the
block layer is also added to ensure that we never see read FUA
commands (current behavior) (me)
- Several patches to move the old PARIDE (parallel port IDE) driver to
libata as pata_parport. Given that this driver also needs protocol
modules, the driver code resides in its own pata_parport directoy
under drivers/ata (Ondrej)
* tag 'ata-6.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/libata:
ata: pata_parport: Fix ida_alloc return value error check
drivers/block: Move PARIDE protocol modules to drivers/ata/pata_parport
drivers/block: Remove PARIDE core and high-level protocols
ata: pata_parport: add driver (PARIDE replacement)
ata: libata: exclude FUA support for known buggy drives
ata: libata: Fix FUA handling in ata_build_rw_tf()
ata: libata: cleanup fua support detection
ata: libata: Rename and cleanup ata_rwcmd_protocol()
ata: libata: Introduce ata_ncq_supported()
block: add a sanity check for non-write flush/fua bios
ata: libata-scsi: improve ata_scsiop_maint_in()
ata: libata-scsi: do not overwrite SCSI ML and status bytes
ata: libata: move NCQ related ATA_DFLAGs
ata: libata: respect successfully completed commands during errors
ata: libata: read the shared status for successful NCQ commands once
ata: libata: simplify qc_fill_rtf port operation interface
ata: scsi: rename flag ATA_QCFLAG_FAILED to ATA_QCFLAG_EH
ata: libata-eh: Cleanup ata_scsi_cmd_error_handler()
ata: octeon: Drop empty platform remove function
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/libata.h | 61 | ||||
-rw-r--r-- | include/linux/pata_parport.h | 111 |
2 files changed, 150 insertions, 22 deletions
diff --git a/include/linux/libata.h b/include/linux/libata.h index c9149ebe7423..a759dfbdcc91 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -90,32 +90,32 @@ enum { ATA_DFLAG_ACPI_FAILED = (1 << 6), /* ACPI on devcfg has failed */ ATA_DFLAG_AN = (1 << 7), /* AN configured */ ATA_DFLAG_TRUSTED = (1 << 8), /* device supports trusted send/recv */ + ATA_DFLAG_FUA = (1 << 9), /* device supports FUA */ ATA_DFLAG_DMADIR = (1 << 10), /* device requires DMADIR */ - ATA_DFLAG_CFG_MASK = (1 << 12) - 1, + ATA_DFLAG_NCQ_SEND_RECV = (1 << 11), /* device supports NCQ SEND and RECV */ + ATA_DFLAG_NCQ_PRIO = (1 << 12), /* device supports NCQ priority */ + ATA_DFLAG_CFG_MASK = (1 << 13) - 1, - ATA_DFLAG_PIO = (1 << 12), /* device limited to PIO mode */ - ATA_DFLAG_NCQ_OFF = (1 << 13), /* device limited to non-NCQ mode */ + ATA_DFLAG_PIO = (1 << 13), /* device limited to PIO mode */ + ATA_DFLAG_NCQ_OFF = (1 << 14), /* device limited to non-NCQ mode */ ATA_DFLAG_SLEEPING = (1 << 15), /* device is sleeping */ ATA_DFLAG_DUBIOUS_XFER = (1 << 16), /* data transfer not verified */ ATA_DFLAG_NO_UNLOAD = (1 << 17), /* device doesn't support unload */ ATA_DFLAG_UNLOCK_HPA = (1 << 18), /* unlock HPA */ - ATA_DFLAG_NCQ_SEND_RECV = (1 << 19), /* device supports NCQ SEND and RECV */ - ATA_DFLAG_NCQ_PRIO = (1 << 20), /* device supports NCQ priority */ - ATA_DFLAG_NCQ_PRIO_ENABLED = (1 << 21), /* Priority cmds sent to dev */ - ATA_DFLAG_INIT_MASK = (1 << 24) - 1, + ATA_DFLAG_INIT_MASK = (1 << 19) - 1, + ATA_DFLAG_NCQ_PRIO_ENABLED = (1 << 19), /* Priority cmds sent to dev */ ATA_DFLAG_DETACH = (1 << 24), ATA_DFLAG_DETACHED = (1 << 25), - ATA_DFLAG_DA = (1 << 26), /* device supports Device Attention */ ATA_DFLAG_DEVSLP = (1 << 27), /* device supports Device Sleep */ ATA_DFLAG_ACPI_DISABLED = (1 << 28), /* ACPI for the device is disabled */ ATA_DFLAG_D_SENSE = (1 << 29), /* Descriptor sense requested */ ATA_DFLAG_ZAC = (1 << 30), /* ZAC device */ - ATA_DFLAG_FEATURES_MASK = ATA_DFLAG_TRUSTED | ATA_DFLAG_DA | \ - ATA_DFLAG_DEVSLP | ATA_DFLAG_NCQ_SEND_RECV | \ - ATA_DFLAG_NCQ_PRIO, + ATA_DFLAG_FEATURES_MASK = (ATA_DFLAG_TRUSTED | ATA_DFLAG_DA | \ + ATA_DFLAG_DEVSLP | ATA_DFLAG_NCQ_SEND_RECV | \ + ATA_DFLAG_NCQ_PRIO | ATA_DFLAG_FUA), ATA_DEV_UNKNOWN = 0, /* unknown device */ ATA_DEV_ATA = 1, /* ATA device */ @@ -200,13 +200,14 @@ enum { /* struct ata_queued_cmd flags */ ATA_QCFLAG_ACTIVE = (1 << 0), /* cmd not yet ack'd to scsi lyer */ ATA_QCFLAG_DMAMAP = (1 << 1), /* SG table is DMA mapped */ + ATA_QCFLAG_RTF_FILLED = (1 << 2), /* result TF has been filled */ ATA_QCFLAG_IO = (1 << 3), /* standard IO command */ ATA_QCFLAG_RESULT_TF = (1 << 4), /* result TF requested */ ATA_QCFLAG_CLEAR_EXCL = (1 << 5), /* clear excl_link on completion */ ATA_QCFLAG_QUIET = (1 << 6), /* don't report device error */ ATA_QCFLAG_RETRY = (1 << 7), /* retry after failure */ - ATA_QCFLAG_FAILED = (1 << 16), /* cmd failed and is owned by EH */ + ATA_QCFLAG_EH = (1 << 16), /* cmd aborted and owned by EH */ ATA_QCFLAG_SENSE_VALID = (1 << 17), /* sense data valid */ ATA_QCFLAG_EH_SCHEDULED = (1 << 18), /* EH scheduled (obsolete) */ @@ -381,6 +382,7 @@ enum { ATA_HORKAGE_NO_NCQ_ON_ATI = (1 << 27), /* Disable NCQ on ATI chipset */ ATA_HORKAGE_NO_ID_DEV_LOG = (1 << 28), /* Identify device log missing */ ATA_HORKAGE_NO_LOG_DIR = (1 << 29), /* Do not read log directory */ + ATA_HORKAGE_NO_FUA = (1 << 30), /* Do not use FUA */ /* DMA mask for user DMA control: User visible values; DO NOT renumber */ @@ -876,7 +878,8 @@ struct ata_port_operations { int (*check_atapi_dma)(struct ata_queued_cmd *qc); enum ata_completion_errors (*qc_prep)(struct ata_queued_cmd *qc); unsigned int (*qc_issue)(struct ata_queued_cmd *qc); - bool (*qc_fill_rtf)(struct ata_queued_cmd *qc); + void (*qc_fill_rtf)(struct ata_queued_cmd *qc); + void (*qc_ncq_fill_rtf)(struct ata_port *ap, u64 done_mask); /* * Configuration and exception handling @@ -1690,21 +1693,35 @@ extern struct ata_device *ata_dev_next(struct ata_device *dev, (dev) = ata_dev_next((dev), (link), ATA_DITER_##mode)) /** - * ata_ncq_enabled - Test whether NCQ is enabled - * @dev: ATA device to test for + * ata_ncq_supported - Test whether NCQ is supported + * @dev: ATA device to test * * LOCKING: * spin_lock_irqsave(host lock) * * RETURNS: - * 1 if NCQ is enabled for @dev, 0 otherwise. + * true if @dev supports NCQ, false otherwise. */ -static inline int ata_ncq_enabled(struct ata_device *dev) +static inline bool ata_ncq_supported(struct ata_device *dev) { if (!IS_ENABLED(CONFIG_SATA_HOST)) - return 0; - return (dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ_OFF | - ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ; + return false; + return (dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ; +} + +/** + * ata_ncq_enabled - Test whether NCQ is enabled + * @dev: ATA device to test + * + * LOCKING: + * spin_lock_irqsave(host lock) + * + * RETURNS: + * true if NCQ is enabled for @dev, false otherwise. + */ +static inline bool ata_ncq_enabled(struct ata_device *dev) +{ + return ata_ncq_supported(dev) && !(dev->flags & ATA_DFLAG_NCQ_OFF); } static inline bool ata_fpdma_dsm_supported(struct ata_device *dev) @@ -1756,7 +1773,7 @@ static inline struct ata_queued_cmd *ata_qc_from_tag(struct ata_port *ap, return qc; if ((qc->flags & (ATA_QCFLAG_ACTIVE | - ATA_QCFLAG_FAILED)) == ATA_QCFLAG_ACTIVE) + ATA_QCFLAG_EH)) == ATA_QCFLAG_ACTIVE) return qc; return NULL; @@ -1936,7 +1953,7 @@ extern void ata_sff_queue_delayed_work(struct delayed_work *dwork, unsigned long delay); extern void ata_sff_queue_pio_task(struct ata_link *link, unsigned long delay); extern unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc); -extern bool ata_sff_qc_fill_rtf(struct ata_queued_cmd *qc); +extern void ata_sff_qc_fill_rtf(struct ata_queued_cmd *qc); extern unsigned int ata_sff_port_intr(struct ata_port *ap, struct ata_queued_cmd *qc); extern irqreturn_t ata_sff_interrupt(int irq, void *dev_instance); diff --git a/include/linux/pata_parport.h b/include/linux/pata_parport.h new file mode 100644 index 000000000000..58781846f282 --- /dev/null +++ b/include/linux/pata_parport.h @@ -0,0 +1,111 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * pata_parport.h (c) 1997-8 Grant R. Guenther <grant@torque.net> + * Under the terms of the GPL. + * + * This file defines the interface for parallel port IDE adapter chip drivers. + */ + +#ifndef LINUX_PATA_PARPORT_H +#define LINUX_PATA_PARPORT_H + +#include <linux/libata.h> + +#define PI_PCD 1 /* dummy for paride protocol modules */ + +struct pi_adapter { + struct device dev; + struct pi_protocol *proto; /* adapter protocol */ + int port; /* base address of parallel port */ + int mode; /* transfer mode in use */ + int delay; /* adapter delay setting */ + int devtype; /* dummy for paride protocol modules */ + char *device; /* dummy for paride protocol modules */ + int unit; /* unit number for chained adapters */ + int saved_r0; /* saved port state */ + int saved_r2; /* saved port state */ + unsigned long private; /* for protocol module */ + struct pardevice *pardev; /* pointer to pardevice */ +}; + +typedef struct pi_adapter PIA; /* for paride protocol modules */ + +/* registers are addressed as (cont,regr) + * cont: 0 for command register file, 1 for control register(s) + * regr: 0-7 for register number. + */ + +/* macros and functions exported to the protocol modules */ +#define delay_p (pi->delay ? udelay(pi->delay) : (void)0) +#define out_p(offs, byte) do { outb(byte, pi->port + offs); delay_p; } while (0) +#define in_p(offs) (delay_p, inb(pi->port + offs)) + +#define w0(byte) out_p(0, byte) +#define r0() in_p(0) +#define w1(byte) out_p(1, byte) +#define r1() in_p(1) +#define w2(byte) out_p(2, byte) +#define r2() in_p(2) +#define w3(byte) out_p(3, byte) +#define w4(byte) out_p(4, byte) +#define r4() in_p(4) +#define w4w(data) do { outw(data, pi->port + 4); delay_p; } while (0) +#define w4l(data) do { outl(data, pi->port + 4); delay_p; } while (0) +#define r4w() (delay_p, inw(pi->port + 4)) +#define r4l() (delay_p, inl(pi->port + 4)) + +static inline u16 pi_swab16(char *b, int k) +{ + union { u16 u; char t[2]; } r; + + r.t[0] = b[2 * k + 1]; r.t[1] = b[2 * k]; + return r.u; +} + +static inline u32 pi_swab32(char *b, int k) +{ + union { u32 u; char f[4]; } r; + + r.f[0] = b[4 * k + 1]; r.f[1] = b[4 * k]; + r.f[2] = b[4 * k + 3]; r.f[3] = b[4 * k + 2]; + return r.u; +} + +struct pi_protocol { + char name[8]; + + int max_mode; + int epp_first; /* modes >= this use 8 ports */ + + int default_delay; + int max_units; /* max chained units probed for */ + + void (*write_regr)(struct pi_adapter *pi, int cont, int regr, int val); + int (*read_regr)(struct pi_adapter *pi, int cont, int regr); + void (*write_block)(struct pi_adapter *pi, char *buf, int count); + void (*read_block)(struct pi_adapter *pi, char *buf, int count); + + void (*connect)(struct pi_adapter *pi); + void (*disconnect)(struct pi_adapter *pi); + + int (*test_port)(struct pi_adapter *pi); + int (*probe_unit)(struct pi_adapter *pi); + int (*test_proto)(struct pi_adapter *pi, char *scratch, int verbose); + void (*log_adapter)(struct pi_adapter *pi, char *scratch, int verbose); + + int (*init_proto)(struct pi_adapter *pi); + void (*release_proto)(struct pi_adapter *pi); + struct module *owner; + struct device_driver driver; + struct scsi_host_template sht; +}; + +#define PATA_PARPORT_SHT ATA_PIO_SHT + +int pata_parport_register_driver(struct pi_protocol *pr); +void pata_parport_unregister_driver(struct pi_protocol *pr); +/* defines for old paride protocol modules */ +#define paride_register pata_parport_register_driver +#define paride_unregister pata_parport_unregister_driver + +#endif /* LINUX_PATA_PARPORT_H */ |