linux/drivers/ata/libahci.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  libahci.c - Common AHCI SATA low-level routines
 *
 *  Maintained by:  Tejun Heo <[email protected]>
 *    		    Please ALWAYS copy [email protected]
 *		    on emails.
 *
 *  Copyright 2004-2005 Red Hat, Inc.
 *
 * libata documentation is available via 'make {ps|pdf}docs',
 * as Documentation/driver-api/libata.rst
 *
 * AHCI hardware documentation:
 * http://www.intel.com/technology/serialata/pdf/rev1_0.pdf
 * http://www.intel.com/technology/serialata/pdf/rev1_1.pdf
 */

#include <linux/bitops.h>
#include <linux/kernel.h>
#include <linux/gfp.h>
#include <linux/module.h>
#include <linux/nospec.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <linux/device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
#include <linux/libata.h>
#include <linux/pci.h>
#include "ahci.h"
#include "libata.h"

static int ahci_skip_host_reset;
int ahci_ignore_sss;
EXPORT_SYMBOL_GPL();

module_param_named(skip_host_reset, ahci_skip_host_reset, int, 0444);
MODULE_PARM_DESC();

module_param_named(ignore_sss, ahci_ignore_sss, int, 0444);
MODULE_PARM_DESC();

static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
			unsigned hints);
static ssize_t ahci_led_show(struct ata_port *ap, char *buf);
static ssize_t ahci_led_store(struct ata_port *ap, const char *buf,
			      size_t size);
static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state,
					ssize_t size);



static int ahci_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
static int ahci_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
static void ahci_qc_fill_rtf(struct ata_queued_cmd *qc);
static void ahci_qc_ncq_fill_rtf(struct ata_port *ap, u64 done_mask);
static int ahci_port_start(struct ata_port *ap);
static void ahci_port_stop(struct ata_port *ap);
static enum ata_completion_errors ahci_qc_prep(struct ata_queued_cmd *qc);
static int ahci_pmp_qc_defer(struct ata_queued_cmd *qc);
static void ahci_freeze(struct ata_port *ap);
static void ahci_thaw(struct ata_port *ap);
static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep);
static void ahci_enable_fbs(struct ata_port *ap);
static void ahci_disable_fbs(struct ata_port *ap);
static void ahci_pmp_attach(struct ata_port *ap);
static void ahci_pmp_detach(struct ata_port *ap);
static int ahci_softreset(struct ata_link *link, unsigned int *class,
			  unsigned long deadline);
static int ahci_pmp_retry_softreset(struct ata_link *link, unsigned int *class,
			  unsigned long deadline);
static int ahci_hardreset(struct ata_link *link, unsigned int *class,
			  unsigned long deadline);
static void ahci_postreset(struct ata_link *link, unsigned int *class);
static void ahci_post_internal_cmd(struct ata_queued_cmd *qc);
static void ahci_dev_config(struct ata_device *dev);
#ifdef CONFIG_PM
static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg);
#endif
static ssize_t ahci_activity_show(struct ata_device *dev, char *buf);
static ssize_t ahci_activity_store(struct ata_device *dev,
				   enum sw_activity val);
static void ahci_init_sw_activity(struct ata_link *link);

static ssize_t ahci_show_host_caps(struct device *dev,
				   struct device_attribute *attr, char *buf);
static ssize_t ahci_show_host_cap2(struct device *dev,
				   struct device_attribute *attr, char *buf);
static ssize_t ahci_show_host_version(struct device *dev,
				      struct device_attribute *attr, char *buf);
static ssize_t ahci_show_port_cmd(struct device *dev,
				  struct device_attribute *attr, char *buf);
static ssize_t ahci_read_em_buffer(struct device *dev,
				   struct device_attribute *attr, char *buf);
static ssize_t ahci_store_em_buffer(struct device *dev,
				    struct device_attribute *attr,
				    const char *buf, size_t size);
static ssize_t ahci_show_em_supported(struct device *dev,
				      struct device_attribute *attr, char *buf);
static irqreturn_t ahci_single_level_irq_intr(int irq, void *dev_instance);

static DEVICE_ATTR(ahci_host_caps, S_IRUGO, ahci_show_host_caps, NULL);
static DEVICE_ATTR(ahci_host_cap2, S_IRUGO, ahci_show_host_cap2, NULL);
static DEVICE_ATTR(ahci_host_version, S_IRUGO, ahci_show_host_version, NULL);
static DEVICE_ATTR(ahci_port_cmd, S_IRUGO, ahci_show_port_cmd, NULL);
static DEVICE_ATTR(em_buffer, S_IWUSR | S_IRUGO,
		   ahci_read_em_buffer, ahci_store_em_buffer);
static DEVICE_ATTR(em_message_supported, S_IRUGO, ahci_show_em_supported, NULL);

static struct attribute *ahci_shost_attrs[] =;

static const struct attribute_group ahci_shost_attr_group =;

const struct attribute_group *ahci_shost_groups[] =;
EXPORT_SYMBOL_GPL();

static struct attribute *ahci_sdev_attrs[] =;

static const struct attribute_group ahci_sdev_attr_group =;

const struct attribute_group *ahci_sdev_groups[] =;
EXPORT_SYMBOL_GPL();

struct ata_port_operations ahci_ops =;
EXPORT_SYMBOL_GPL();

struct ata_port_operations ahci_pmp_retry_srst_ops =;
EXPORT_SYMBOL_GPL();

static bool ahci_em_messages __read_mostly =;
module_param(ahci_em_messages, bool, 0444);
/* add other LED protocol types when they become supported */
MODULE_PARM_DESC();

/* device sleep idle timeout in ms */
static int devslp_idle_timeout __read_mostly =;
module_param(devslp_idle_timeout, int, 0644);
MODULE_PARM_DESC();

static void ahci_enable_ahci(void __iomem *mmio)
{}

/**
 *	ahci_rpm_get_port - Make sure the port is powered on
 *	@ap: Port to power on
 *
 *	Whenever there is need to access the AHCI host registers outside of
 *	normal execution paths, call this function to make sure the host is
 *	actually powered on.
 */
static int ahci_rpm_get_port(struct ata_port *ap)
{}

/**
 *	ahci_rpm_put_port - Undoes ahci_rpm_get_port()
 *	@ap: Port to power down
 *
 *	Undoes ahci_rpm_get_port() and possibly powers down the AHCI host
 *	if it has no more active users.
 */
static void ahci_rpm_put_port(struct ata_port *ap)
{}

static ssize_t ahci_show_host_caps(struct device *dev,
				   struct device_attribute *attr, char *buf)
{}

static ssize_t ahci_show_host_cap2(struct device *dev,
				   struct device_attribute *attr, char *buf)
{}

static ssize_t ahci_show_host_version(struct device *dev,
				   struct device_attribute *attr, char *buf)
{}

static ssize_t ahci_show_port_cmd(struct device *dev,
				  struct device_attribute *attr, char *buf)
{}

static ssize_t ahci_read_em_buffer(struct device *dev,
				   struct device_attribute *attr, char *buf)
{}

static ssize_t ahci_store_em_buffer(struct device *dev,
				    struct device_attribute *attr,
				    const char *buf, size_t size)
{}

static ssize_t ahci_show_em_supported(struct device *dev,
				      struct device_attribute *attr, char *buf)
{}

/**
 *	ahci_save_initial_config - Save and fixup initial config values
 *	@dev: target AHCI device
 *	@hpriv: host private area to store config values
 *
 *	Some registers containing configuration info might be setup by
 *	BIOS and might be cleared on reset.  This function saves the
 *	initial values of those registers into @hpriv such that they
 *	can be restored after controller reset.
 *
 *	If inconsistent, config values are fixed up by this function.
 *
 *	If it is not set already this function sets hpriv->start_engine to
 *	ahci_start_engine.
 *
 *	LOCKING:
 *	None.
 */
void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv)
{}
EXPORT_SYMBOL_GPL();

/**
 *	ahci_restore_initial_config - Restore initial config
 *	@host: target ATA host
 *
 *	Restore initial config stored by ahci_save_initial_config().
 *
 *	LOCKING:
 *	None.
 */
static void ahci_restore_initial_config(struct ata_host *host)
{}

static unsigned ahci_scr_offset(struct ata_port *ap, unsigned int sc_reg)
{}

static int ahci_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val)
{}

static int ahci_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
{}

void ahci_start_engine(struct ata_port *ap)
{}
EXPORT_SYMBOL_GPL();

int ahci_stop_engine(struct ata_port *ap)
{}
EXPORT_SYMBOL_GPL();

void ahci_start_fis_rx(struct ata_port *ap)
{}
EXPORT_SYMBOL_GPL();

static int ahci_stop_fis_rx(struct ata_port *ap)
{}

static void ahci_power_up(struct ata_port *ap)
{}

static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
			unsigned int hints)
{}

#ifdef CONFIG_PM
static void ahci_power_down(struct ata_port *ap)
{}
#endif

static void ahci_start_port(struct ata_port *ap)
{}

static int ahci_deinit_port(struct ata_port *ap, const char **emsg)
{}

int ahci_reset_controller(struct ata_host *host)
{}
EXPORT_SYMBOL_GPL();

static void ahci_sw_activity(struct ata_link *link)
{}

static void ahci_sw_activity_blink(struct timer_list *t)
{}

static void ahci_init_sw_activity(struct ata_link *link)
{}

int ahci_reset_em(struct ata_host *host)
{}
EXPORT_SYMBOL_GPL();

static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state,
					ssize_t size)
{}

static ssize_t ahci_led_show(struct ata_port *ap, char *buf)
{}

static ssize_t ahci_led_store(struct ata_port *ap, const char *buf,
				size_t size)
{}

static ssize_t ahci_activity_store(struct ata_device *dev, enum sw_activity val)
{}

static ssize_t ahci_activity_show(struct ata_device *dev, char *buf)
{}

static void ahci_port_clear_pending_irq(struct ata_port *ap)
{}

static void ahci_port_init(struct device *dev, struct ata_port *ap,
			   int port_no, void __iomem *mmio,
			   void __iomem *port_mmio)
{}

void ahci_init_controller(struct ata_host *host)
{}
EXPORT_SYMBOL_GPL();

static void ahci_dev_config(struct ata_device *dev)
{}

unsigned int ahci_dev_classify(struct ata_port *ap)
{}
EXPORT_SYMBOL_GPL();

void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
			u32 opts)
{}
EXPORT_SYMBOL_GPL();

int ahci_kick_engine(struct ata_port *ap)
{}
EXPORT_SYMBOL_GPL();

static int ahci_exec_polled_cmd(struct ata_port *ap, int pmp,
				struct ata_taskfile *tf, int is_cmd, u16 flags,
				unsigned int timeout_msec)
{}

int ahci_do_softreset(struct ata_link *link, unsigned int *class,
		      int pmp, unsigned long deadline,
		      int (*check_ready)(struct ata_link *link))
{}

int ahci_check_ready(struct ata_link *link)
{}
EXPORT_SYMBOL_GPL();

static int ahci_softreset(struct ata_link *link, unsigned int *class,
			  unsigned long deadline)
{}
EXPORT_SYMBOL_GPL();

static int ahci_bad_pmp_check_ready(struct ata_link *link)
{}

static int ahci_pmp_retry_softreset(struct ata_link *link, unsigned int *class,
				    unsigned long deadline)
{}

int ahci_do_hardreset(struct ata_link *link, unsigned int *class,
		      unsigned long deadline, bool *online)
{}
EXPORT_SYMBOL_GPL();

static int ahci_hardreset(struct ata_link *link, unsigned int *class,
			  unsigned long deadline)
{}

static void ahci_postreset(struct ata_link *link, unsigned int *class)
{}

static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl)
{}

static int ahci_pmp_qc_defer(struct ata_queued_cmd *qc)
{}

static enum ata_completion_errors ahci_qc_prep(struct ata_queued_cmd *qc)
{}

static void ahci_fbs_dec_intr(struct ata_port *ap)
{}

static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
{}

static void ahci_qc_complete(struct ata_port *ap, void __iomem *port_mmio)
{}

static void ahci_handle_port_interrupt(struct ata_port *ap,
				       void __iomem *port_mmio, u32 status)
{}

static void ahci_port_intr(struct ata_port *ap)
{}

static irqreturn_t ahci_multi_irqs_intr_hard(int irq, void *dev_instance)
{}

u32 ahci_handle_port_intr(struct ata_host *host, u32 irq_masked)
{}
EXPORT_SYMBOL_GPL();

static irqreturn_t ahci_single_level_irq_intr(int irq, void *dev_instance)
{}

unsigned int ahci_qc_issue(struct ata_queued_cmd *qc)
{}
EXPORT_SYMBOL_GPL();

static void ahci_qc_fill_rtf(struct ata_queued_cmd *qc)
{}

static void ahci_qc_ncq_fill_rtf(struct ata_port *ap, u64 done_mask)
{}

static void ahci_freeze(struct ata_port *ap)
{}

static void ahci_thaw(struct ata_port *ap)
{}

void ahci_error_handler(struct ata_port *ap)
{}
EXPORT_SYMBOL_GPL();

static void ahci_post_internal_cmd(struct ata_queued_cmd *qc)
{}

static void ahci_set_aggressive_devslp(struct ata_port *ap, bool sleep)
{}

static void ahci_enable_fbs(struct ata_port *ap)
{}

static void ahci_disable_fbs(struct ata_port *ap)
{}

static void ahci_pmp_attach(struct ata_port *ap)
{}

static void ahci_pmp_detach(struct ata_port *ap)
{}

int ahci_port_resume(struct ata_port *ap)
{}
EXPORT_SYMBOL_GPL();

#ifdef CONFIG_PM
static void ahci_handle_s2idle(struct ata_port *ap)
{}

static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
{}
#endif

static int ahci_port_start(struct ata_port *ap)
{}

static void ahci_port_stop(struct ata_port *ap)
{}

void ahci_print_info(struct ata_host *host, const char *scc_s)
{}
EXPORT_SYMBOL_GPL();

void ahci_set_em_messages(struct ahci_host_priv *hpriv,
			  struct ata_port_info *pi)
{}
EXPORT_SYMBOL_GPL();

static int ahci_host_activate_multi_irqs(struct ata_host *host,
					 const struct scsi_host_template *sht)
{}

/**
 *	ahci_host_activate - start AHCI host, request IRQs and register it
 *	@host: target ATA host
 *	@sht: scsi_host_template to use when registering the host
 *
 *	LOCKING:
 *	Inherited from calling layer (may sleep).
 *
 *	RETURNS:
 *	0 on success, -errno otherwise.
 */
int ahci_host_activate(struct ata_host *host, const struct scsi_host_template *sht)
{}
EXPORT_SYMBOL_GPL();

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();