libata: prep for PMP support, take 4
PATCH 3/4 libata: prep for PMP support, take 4
Hello, all.
This is the fourth take of libata-pmp-prep patchset. This patchset contains 12 patches implementing various stuff needed for PMP.
#01 : add PMP related constants
#02-04 : various small stuff
#05-06 : qc_defer mechanism implementation
#07-11 : link/device quirks and EH fast-fail path - things needed to
handle quirky PMP fan-out links / pseudo devices.
#12 : SATA SDB notify handler
Changes from the last take[L] are.
* PMP related constants patch moved here from pmp patchset
* qc_defer CLEAR_EXCL fixed to clear excl_link iff it points to self
* addition of various quirks/special case handling vital for supporting first-gen PMP chips
* generalized SDB notify handling
This patchset is against
libata-dev#upstream (4e1ae96828f6cee7b89ab8ca474c150fe211afd8)
+ [1] misc-updates patchset
+ [2] libata-link patchset, take 4
Thanks.
--
tejun
[L] http://thread.gmane.org/gmane.linux.ide/13500
[1] http://thread.gmane.org/gmane.linux.ide/20081
[2] http://thread.gmane.org/gmane.linux.ide/20099
PATCH 1/12 libata-pmp: add PMP related constants, fields, ops and update helpers
Add PMP related constants, fields and ops. Also, update ata_class_enabled/disabled() such that PMP classes are considered.
--- include/linux/libata.h | 31 +++++++++++++++++++++++++++---- 1 files changed, 27 insertions(+), 4 deletions(-)
include/linux/libata.h +27 -4
@@ -153,7 +153,11 @@ enum {ATA_DEV_ATA_UNSUP =2 ,/* ATA device (unsupported) */ ATA_DEV_ATAPI =3 ,/* ATAPI device */ ATA_DEV_ATAPI_UNSUP =4 ,/* ATAPI device (unsupported) */ -ATA_DEV_NONE =5 ,/* no device */ +ATA_DEV_PMP =5 ,/* SATA port multiplier */ +ATA_DEV_PMP_UNSUP =6 ,/* SATA port multiplier (unsupported) */ +ATA_DEV_SEMB =7 ,/* SEMB */ +ATA_DEV_SEMB_UNSUP =8 ,/* SEMB (unsupported) */ +ATA_DEV_NONE =9 ,/* no device */ /* struct ata_link flags */ ATA_LFLAG_HRST_TO_RESUME = (1 << 0), /* hardreset to resume link */
@@ -178,6 +182,8 @@ enum {ATA_FLAG_IGN_SIMPLEX = (1 <<15 ),/* ignore SIMPLEX */ ATA_FLAG_NO_IORDY = (1 <<16 ),/* controller lacks iordy */ ATA_FLAG_ACPI_SATA = (1 <<17 ),/* need native SATA ACPI layout */ +ATA_FLAG_PMP = (1 <<18 ), +ATA_FLAG_SDB_NOTIFY = (1 <<19 ),/* The following flag belongs to ap->pflags but is kept in * ap->flags because it's referenced in many LLDs and will be
@@ -295,6 +301,10 @@ enum {/* how hard are we gonna try to probe/recover devices */ ATA_PROBE_MAX_TRIES =3 ,ATA_EH_DEV_TRIES =3 , +ATA_EH_PMP_TRIES =5 , +ATA_EH_PMP_LINK_TRIES =3 , + +SATA_PMP_SCR_TIMEOUT =250 ,/* Horkage types. May be set by libata or controller on drives (some horkage may be drive/controller pair dependant */
@@ -445,7 +455,12 @@ struct ata_device {/* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */ u64 n_sectors;/* size of device, if ATA */ unsigned int class;/* ATA_DEV_xxx */ -u16 id[ATA_ID_WORDS ];/* IDENTIFY xxx DEVICE data */ + +union { +u16 id[ATA_ID_WORDS ];/* IDENTIFY xxx DEVICE data */ +u32 gscr[SATA_PMP_GSCR_DWORDS ];/* PMP GSCR block */ + }; +u8 pio_mode;u8 dma_mode;u8 xfer_mode;
@@ -625,6 +640,12 @@ struct ata_port_operations {void (*qc_prep) (struct ata_queued_cmd *qc);unsigned int (*qc_issue) (struct ata_queued_cmd *qc); +/* port multiplier */ +void (*pmp_attach) (struct ata_port *ap); +void (*pmp_detach) (struct ata_port *ap); +int (*pmp_read) (struct ata_device *dev,int pmp,int reg,u32 *r_val); +int (*pmp_write) (struct ata_device *dev,int pmp,int reg,u32 val); +/* Error handlers. ->error_handler overrides ->eng_timeout and * indicates that new-style EH is in place. */
@@ -1020,12 +1041,14 @@ static inline unsigned int ata_tag_internal(unsigned int tag)*/ static inline unsigned int ata_class_enabled (unsigned int class) { -return class ==ATA_DEV_ATA || class ==ATA_DEV_ATAPI ; +return class ==ATA_DEV_ATA || class ==ATA_DEV_ATAPI || + class ==ATA_DEV_PMP || class ==ATA_DEV_SEMB ; }static inline unsigned int ata_class_disabled (unsigned int class) { -return class ==ATA_DEV_ATA_UNSUP || class ==ATA_DEV_ATAPI_UNSUP ; +return class ==ATA_DEV_ATA_UNSUP || class ==ATA_DEV_ATAPI_UNSUP || + class ==ATA_DEV_PMP_UNSUP || class ==ATA_DEV_SEMB_UNSUP ; }static inline unsigned int ata_class_absent (unsigned int class)
Signature · 1 line
1.5.0.3
PATCH 2/12 libata-pmp-prep: add @new_class to ata_dev_revalidate()
In reply to Tejun HeoConsider newly found class code while revalidating. PMP resetting always results in valid class code and issuing PMP commands to ATA/ATAPI device isn't very attractive. Add @new_class to ata_dev_revalidate() and check class code for revalidation.
--- drivers/ata/libata-core.c | 15 +++++++++++++-- drivers/ata/libata-eh.c | 3 ++- drivers/ata/libata.h | 3 ++- 3 files changed, 17 insertions(+), 4 deletions(-)
drivers/ata/libata-core.c +13 -2
@@ -2790,7 +2790,7 @@ static int ata_dev_set_mode(struct ata_device *dev) } ehc->i.flags |=ATA_EHI_POST_SETMODE ; - rc =ata_dev_revalidate (dev,0 ); + rc =ata_dev_revalidate (dev,ATA_DEV_UNKNOWN ,0 ); ehc->i.flags &= ~ATA_EHI_POST_SETMODE ;if (rc)return rc;
@@ -3699,6 +3699,7 @@ int ata_dev_reread_id(struct ata_device *dev, unsigned int readid_flags)/** * ata_dev_revalidate - Revalidate ATA device * @dev: device to revalidate +* @new_class: new class code * @readid_flags: read ID flags * * Re-read IDENTIFY page, make sure @dev is still attached to the
@@ -3710,7 +3711,8 @@ int ata_dev_reread_id(struct ata_device *dev, unsigned int readid_flags)* RETURNS: * 0 on success, negative errno otherwise */ -int ata_dev_revalidate (struct ata_device *dev,unsigned int readid_flags) +int ata_dev_revalidate (struct ata_device *dev,unsigned int new_class, +unsigned int readid_flags) {u64 n_sectors = dev->n_sectors;int rc;
@@ -3718,6 +3720,15 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int readid_flags)if (!ata_dev_enabled (dev))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 ) { +ata_dev_printk (dev,KERN_INFO ,"class mismatch %u != %u\n" , + dev->class, new_class); + rc = -ENODEV ; + goto fail; + } +/* re-read ID */ rc =ata_dev_reread_id (dev, readid_flags);if (rc)
drivers/ata/libata-eh.c +2 -1
@@ -1966,7 +1966,8 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link, }ata_eh_about_to_do (link, dev,ATA_EH_REVALIDATE ); - rc =ata_dev_revalidate (dev, readid_flags); + rc =ata_dev_revalidate (dev, ehc->classes[dev->devno], + readid_flags);if (rc) goto err;
drivers/ata/libata.h +2 -1
@@ -76,7 +76,8 @@ extern unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd);extern int ata_dev_read_id (struct ata_device *dev,unsigned int *p_class,unsigned int flags,u16 *id);extern int ata_dev_reread_id (struct ata_device *dev,unsigned int readid_flags); -extern int ata_dev_revalidate (struct ata_device *dev,unsigned int readid_flags); +extern int ata_dev_revalidate (struct ata_device *dev,unsigned int new_class, +unsigned int readid_flags);extern int ata_dev_configure (struct ata_device *dev);extern int sata_down_spd_limit (struct ata_link *link);extern int sata_set_spd_needed (struct ata_link *link);
Signature · 1 line
1.5.0.3
PATCH 3/12 libata-pmp-prep: make a number of functions global to libata
In reply to Tejun HeoMake a number of functions from libata-core.c and libata-eh.c global to libata (drivers/ata/libata.h). These will be used by PMP.
--- drivers/ata/libata-core.c | 4 ++-- drivers/ata/libata-eh.c | 31 +++++++++++++++---------------- drivers/ata/libata.h | 17 +++++++++++++++++ 3 files changed, 34 insertions(+), 18 deletions(-)
drivers/ata/libata-core.c +2 -2
@@ -6010,7 +6010,7 @@ void ata_dev_init(struct ata_device *dev)* LOCKING: * Kernel thread context (may sleep) */ -static void ata_link_init (struct ata_port *ap,struct ata_link *link,int pmp) +void ata_link_init (struct ata_port *ap,struct ata_link *link,int pmp) {int i;
@@ -6045,7 +6045,7 @@ static void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp)* RETURNS: * 0 on success, -errno on failure. */ -static int sata_link_init_spd_limit (struct ata_link *link) +int sata_link_init_spd_limit (struct ata_link *link) {u32 scontrol, spd;int rc;
drivers/ata/libata-eh.c +15 -16
@@ -74,7 +74,6 @@ static const unsigned long ata_eh_reset_timeouts[] = { };static void __ata_port_freeze (struct ata_port *ap); -static void ata_eh_finish (struct ata_port *ap);#ifdef CONFIG_PM static void ata_eh_handle_port_suspend (struct ata_port *ap);static void ata_eh_handle_port_resume (struct ata_port *ap);
@@ -883,7 +882,7 @@ void ata_eh_qc_retry(struct ata_queued_cmd *qc)* LOCKING: * None. */ -static void ata_eh_detach_dev (struct ata_device *dev) +void ata_eh_detach_dev (struct ata_device *dev) {struct ata_link *link = dev->link;struct ata_port *ap = link->ap;
@@ -920,8 +919,8 @@ static void ata_eh_detach_dev(struct ata_device *dev)* LOCKING: * None. */ -static void ata_eh_about_to_do (struct ata_link *link,struct ata_device *dev, -unsigned int action) +void ata_eh_about_to_do (struct ata_link *link,struct ata_device *dev, +unsigned int action) {struct ata_port *ap = link->ap;struct ata_eh_info *ehi = &link->eh_info;
@@ -963,8 +962,8 @@ static void ata_eh_about_to_do(struct ata_link *link, struct ata_device *dev,* LOCKING: * None. */ -static void ata_eh_done (struct ata_link *link,struct ata_device *dev, -unsigned int action) +void ata_eh_done (struct ata_link *link,struct ata_device *dev, +unsigned int action) {struct ata_eh_context *ehc = &link->eh_context;
@@ -1624,7 +1623,7 @@ static void ata_eh_link_autopsy(struct ata_link *link)* LOCKING: * Kernel thread context (may sleep). */ -static void ata_eh_autopsy (struct ata_port *ap) +void ata_eh_autopsy (struct ata_port *ap) {struct ata_link *link;
@@ -1729,7 +1728,7 @@ static void ata_eh_link_report(struct ata_link *link)* LOCKING: * None. */ -static void ata_eh_report (struct ata_port *ap) +void ata_eh_report (struct ata_port *ap) {struct ata_link *link;
@@ -1780,9 +1779,9 @@ static int ata_eh_followup_srst_needed(int rc, int classify,return 0 ; } -static int ata_eh_reset (struct ata_link *link,int classify, -ata_prereset_fn_t prereset,ata_reset_fn_t softreset, -ata_reset_fn_t hardreset,ata_postreset_fn_t postreset) +int ata_eh_reset (struct ata_link *link,int classify, +ata_prereset_fn_t prereset,ata_reset_fn_t softreset, +ata_reset_fn_t hardreset,ata_postreset_fn_t postreset) {struct ata_eh_context *ehc = &link->eh_context;unsigned int *classes = ehc->classes;
@@ -2158,10 +2157,10 @@ static int ata_eh_handle_dev_fail(struct ata_device *dev, int err)* RETURNS: * 0 on success, -errno on failure. */ -static int ata_eh_recover (struct ata_port *ap,ata_prereset_fn_t prereset, -ata_reset_fn_t softreset,ata_reset_fn_t hardreset, -ata_postreset_fn_t postreset, -struct ata_link **r_failed_link) +int ata_eh_recover (struct ata_port *ap,ata_prereset_fn_t prereset, +ata_reset_fn_t softreset,ata_reset_fn_t hardreset, +ata_postreset_fn_t postreset, +struct ata_link **r_failed_link) {struct ata_link *link;struct ata_device *dev;
@@ -2307,7 +2306,7 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,* LOCKING: * None. */ -static void ata_eh_finish (struct ata_port *ap) +void ata_eh_finish (struct ata_port *ap) {int tag;
drivers/ata/libata.h +17 -0
@@ -93,6 +93,8 @@ extern void ata_dev_select(struct ata_port *ap, unsigned int device,extern void swap_buf_le16 (u16 *buf,unsigned int buf_words);extern int ata_flush_cache (struct ata_device *dev);extern void ata_dev_init (struct ata_device *dev); +extern void ata_link_init (struct ata_port *ap,struct ata_link *link,int pmp); +extern int sata_link_init_spd_limit (struct ata_link *link);extern int ata_task_ioctl (struct scsi_device *scsidev,void __user *arg);extern int ata_cmd_ioctl (struct scsi_device *scsidev,void __user *arg);extern struct ata_port *ata_port_alloc (struct ata_host *host);
@@ -154,6 +156,21 @@ extern void ata_scsi_error(struct Scsi_Host *host);extern void ata_port_wait_eh (struct ata_port *ap);extern void ata_eh_fastdrain_timerfn (unsigned long arg);extern void ata_qc_schedule_eh (struct ata_queued_cmd *qc); +extern void ata_eh_detach_dev (struct ata_device *dev); +extern void ata_eh_about_to_do (struct ata_link *link,struct ata_device *dev, +unsigned int action); +extern void ata_eh_done (struct ata_link *link,struct ata_device *dev, +unsigned int action); +extern void ata_eh_autopsy (struct ata_port *ap); +extern void ata_eh_report (struct ata_port *ap); +extern int ata_eh_reset (struct ata_link *link,int classify, +ata_prereset_fn_t prereset,ata_reset_fn_t softreset, +ata_reset_fn_t hardreset,ata_postreset_fn_t postreset); +extern int ata_eh_recover (struct ata_port *ap,ata_prereset_fn_t prereset, +ata_reset_fn_t softreset,ata_reset_fn_t hardreset, +ata_postreset_fn_t postreset, +struct ata_link **r_failed_disk); +extern void ata_eh_finish (struct ata_port *ap);/* libata-sff.c */ extern u8 ata_irq_on (struct ata_port *ap);
Signature · 1 line
1.5.0.3
PATCH 4/12 libata-pmp-prep: add @is_cmd to ata_tf_to_fis()
In reply to Tejun HeoAdd @is_cmd to ata_tf_to_fis(). This controls bit 7 of the second byte which tells the device whether this H2D FIS is for a command or not. This cleans up ahci a bit and will be used by PMP.
--- drivers/ata/ahci.c | 10 ++++------ drivers/ata/libata-core.c | 14 ++++++++------ drivers/ata/sata_qstor.c | 2 +- drivers/ata/sata_sil24.c | 2 +- include/linux/libata.h | 3 ++- 5 files changed, 16 insertions(+), 15 deletions(-)
drivers/ata/ahci.c +4 -6
@@ -994,8 +994,7 @@ static int ahci_softreset(struct ata_link *link, unsigned int *class, cmd_fis_len | AHCI_CMD_RESET | AHCI_CMD_CLR_BUSY); tf.ctl |=ATA_SRST ; -ata_tf_to_fis (&tf, fis,0 ); - fis[1 ] &= ~(1 <<7 );/* turn off Command FIS bit */ +ata_tf_to_fis (&tf,0 ,0 , fis);writel (1 , port_mmio +PORT_CMD_ISSUE );
@@ -1013,8 +1012,7 @@ static int ahci_softreset(struct ata_link *link, unsigned int *class,ahci_fill_cmd_slot (pp,0 , cmd_fis_len); tf.ctl &= ~ATA_SRST ; -ata_tf_to_fis (&tf, fis,0 ); - fis[1 ] &= ~(1 <<7 );/* turn off Command FIS bit */ +ata_tf_to_fis (&tf,0 ,0 , fis);writel (1 , port_mmio +PORT_CMD_ISSUE );readl (port_mmio +PORT_CMD_ISSUE );/* flush */
@@ -1063,7 +1061,7 @@ static int ahci_hardreset(struct ata_link *link, unsigned int *class,/* clear D2H reception area to properly wait for D2H FIS */ ata_tf_init (link->device, &tf); tf.command =0x80 ; -ata_tf_to_fis (&tf, d2h_fis,0 ); +ata_tf_to_fis (&tf,0 ,0 , d2h_fis); rc =sata_std_hardreset (link, class, deadline);
@@ -1184,7 +1182,7 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc)*/ cmd_tbl = pp->cmd_tbl + qc->tag *AHCI_CMD_TBL_SZ ; -ata_tf_to_fis (&qc->tf, cmd_tbl,0 ); +ata_tf_to_fis (&qc->tf,0 ,1 , cmd_tbl);if (is_atapi) {memset (cmd_tbl +AHCI_CMD_TBL_CDB ,0 ,32 );memcpy (cmd_tbl +AHCI_CMD_TBL_CDB , qc->cdb, qc->dev->cdb_len);
drivers/ata/libata-core.c +8 -6
@@ -110,8 +110,9 @@ MODULE_VERSION(DRV_VERSION);/** * ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure * @tf: Taskfile to convert -* @fis: Buffer into which data will output * @pmp: Port multiplier port +* @is_cmd: This FIS is for command +* @fis: Buffer into which data will output * * Converts a standard ATA taskfile to a Serial ATA * FIS structure (Register - Host to Device).
@@ -119,12 +120,13 @@ MODULE_VERSION(DRV_VERSION);* LOCKING: * Inherited from caller. */ - -void ata_tf_to_fis (const struct ata_taskfile *tf,u8 *fis,u8 pmp) +void ata_tf_to_fis (const struct ata_taskfile *tf,u8 pmp,int is_cmd,u8 *fis) { - fis[0 ] =0x27 ;/* Register - Host to Device FIS */ - fis[1 ] = (pmp &0xf ) | (1 <<7 );/* Port multiplier number, -bit 7 indicates Command FIS */ + fis[0 ] =0x27 ;/* Register - Host to Device FIS */ + fis[1 ] = pmp &0xf ;/* Port multiplier number*/ +if (is_cmd) + fis[1 ] |= (1 <<7 );/* bit 7 indicates Command FIS */ + fis[2 ] = tf->command; fis[3 ] = tf->feature;
drivers/ata/sata_qstor.c +1 -1
@@ -339,7 +339,7 @@ static void qs_qc_prep(struct ata_queued_cmd *qc) buf[28 ] = dflags;/* frame information structure (FIS) */ -ata_tf_to_fis (&qc->tf, &buf[32 ],0 ); +ata_tf_to_fis (&qc->tf,0 ,1 , &buf[32 ]); }static inline void qs_packet_start (struct ata_queued_cmd *qc)
drivers/ata/sata_sil24.c +1 -1
@@ -709,7 +709,7 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc) } prb->ctrl =cpu_to_le16 (ctrl); -ata_tf_to_fis (&qc->tf, prb->fis,0 ); +ata_tf_to_fis (&qc->tf, qc->dev->link->pmp,1 , prb->fis);if (qc->flags &ATA_QCFLAG_DMAMAP )sil24_fill_sg (qc, sge);
include/linux/libata.h +2 -1
@@ -806,7 +806,8 @@ extern unsigned int ata_dev_try_classify(struct ata_port *, unsigned int, u8 *);*/ extern void ata_tf_load (struct ata_port *ap,const struct ata_taskfile *tf);extern void ata_tf_read (struct ata_port *ap,struct ata_taskfile *tf); -extern void ata_tf_to_fis (const struct ata_taskfile *tf,u8 *fis,u8 pmp); +extern void ata_tf_to_fis (const struct ata_taskfile *tf, +u8 pmp,int is_cmd,u8 *fis);extern void ata_tf_from_fis (const u8 *fis,struct ata_taskfile *tf);extern void ata_noop_dev_select (struct ata_port *ap,unsigned int device);extern void ata_std_dev_select (struct ata_port *ap,unsigned int device);
Signature · 1 line
1.5.0.3
PATCH 5/12 libata-pmp-prep: implement ops->qc_defer()
In reply to Tejun HeoControllers which support PMP have various restrictions on which combinations of commands are allowed to what number of devices concurrently. This patch implements ops->qc_defer() which determines whether a qc can be issued at the moment or should be deferred.
If the function returns ATA_DEFER_LINK, the qc will be deferred until a qc completes on the link. If ATA_DEFER_PORT, until a qc completes on any link. The defer conditions are advisory and in general ATA_DEFER_LINK can be considered as lower priority deferring than ATA_DEFER_PORT.
ops->qc_defer() replaces fixed ata_scmd_need_defer(). For standard NCQ/non-NCQ exclusion, ata_std_qc_defer() is implemented. ahci and sata_sil24 are converted to use ata_std_qc_defer().
ops->qc_defer() is heavier than the original mechanism because full qc is prepped before determining to defer it, but various information is needed to determine defer conditinos and fully translating a qc is the only way to supply such information in generic manner.
IMHO, this shouldn't cause any noticeable performance issues as
* for most cases deferring occurs rarely (except for NCQ-aware cmd-switching PMP)
* translation itself isn't that expensive
* once deferred the command won't be repeated until another command completes which usually is a very long time cpu-wise.
--- drivers/ata/ahci.c | 2 + drivers/ata/libata-core.c | 31 ++++++++++++++++++++++ drivers/ata/libata-scsi.c | 62 +++++++++++++++++++-------------------------- drivers/ata/sata_nv.c | 1 + drivers/ata/sata_sil24.c | 1 + include/linux/libata.h | 6 ++++ 6 files changed, 67 insertions(+), 36 deletions(-)
drivers/ata/ahci.c +2 -0
@@ -267,6 +267,7 @@ static const struct ata_port_operations ahci_ops = { .tf_read = ahci_tf_read, + .qc_defer = ata_std_qc_defer, .qc_prep = ahci_qc_prep, .qc_issue = ahci_qc_issue,
@@ -301,6 +302,7 @@ static const struct ata_port_operations ahci_vt8251_ops = { .tf_read = ahci_tf_read, + .qc_defer = ata_std_qc_defer, .qc_prep = ahci_qc_prep, .qc_issue = ahci_qc_issue,
drivers/ata/libata-core.c +31 -0
@@ -4160,6 +4160,36 @@ int ata_check_atapi_dma(struct ata_queued_cmd *qc) }/** +* ata_std_qc_defer - Check whether a qc needs to be deferred +* @qc: ATA command in question +* +* Non-NCQ commands cannot run with any other command, NCQ or +* not. As upper layer only knows the queue depth, we are +* responsible for maintaining exclusion. This function checks +* whether a new command @qc can be issued. +* +* LOCKING: +* spin_lock_irqsave(host lock) +* +* RETURNS: +* ATA_DEFER_* if deferring is needed, 0 otherwise. +*/ +int ata_std_qc_defer (struct ata_queued_cmd *qc) +{ +struct ata_link *link = qc->dev->link; + +if (qc->tf.protocol ==ATA_PROT_NCQ ) { +if (!ata_tag_valid (link->active_tag)) +return 0 ; + }else { +if (!ata_tag_valid (link->active_tag) && !link->sactive) +return 0 ; + } + +return ATA_DEFER_LINK ; +} + +/** * ata_qc_prep - Prepare taskfile for submission * @qc: Metadata associated with taskfile to be prepared *
@@ -6921,6 +6951,7 @@ EXPORT_SYMBOL_GPL(ata_interrupt);EXPORT_SYMBOL_GPL (ata_do_set_mode);EXPORT_SYMBOL_GPL (ata_data_xfer);EXPORT_SYMBOL_GPL (ata_data_xfer_noirq); +EXPORT_SYMBOL_GPL (ata_std_qc_defer);EXPORT_SYMBOL_GPL (ata_qc_prep);EXPORT_SYMBOL_GPL (ata_noop_qc_prep);EXPORT_SYMBOL_GPL (ata_bmdma_setup);
drivers/ata/libata-scsi.c +26 -36
103 lines not on this page · raw message
drivers/ata/sata_nv.c +1 -0
@@ -429,6 +429,7 @@ static const struct ata_port_operations nv_adma_ops = { .bmdma_start = ata_bmdma_start, .bmdma_stop = ata_bmdma_stop, .bmdma_status = ata_bmdma_status, + .qc_defer = ata_std_qc_defer, .qc_prep = nv_adma_qc_prep, .qc_issue = nv_adma_qc_issue, .freeze = nv_adma_freeze,
drivers/ata/sata_sil24.c +1 -0
@@ -394,6 +394,7 @@ static const struct ata_port_operations sil24_ops = { .tf_read = sil24_tf_read, + .qc_defer = ata_std_qc_defer, .qc_prep = sil24_qc_prep, .qc_issue = sil24_qc_issue,
include/linux/libata.h +6 -0
@@ -269,6 +269,10 @@ enum {/* ering size */ ATA_ERING_SIZE =32 , +/* return values for ->qc_defer */ +ATA_DEFER_LINK =1 , +ATA_DEFER_PORT =2 , +/* desc_len for ata_eh_info and context */ ATA_EH_DESC_LEN = 80,
@@ -637,6 +641,7 @@ struct ata_port_operations {void (*data_xfer) (struct ata_device *,unsigned char *,unsigned int ,int ); +int (*qc_defer) (struct ata_queued_cmd *qc);void (*qc_prep) (struct ata_queued_cmd *qc);unsigned int (*qc_issue) (struct ata_queued_cmd *qc);
@@ -821,6 +826,7 @@ extern void ata_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data);extern void ata_data_xfer_noirq (struct ata_device *adev,unsigned char *buf,unsigned int buflen,int write_data); +extern int ata_std_qc_defer (struct ata_queued_cmd *qc);extern void ata_qc_prep (struct ata_queued_cmd *qc);extern void ata_noop_qc_prep (struct ata_queued_cmd *qc);extern unsigned int ata_qc_issue_prot (struct ata_queued_cmd *qc);
Signature · 1 line
1.5.0.3
PATCH 6/12 libata-pmp-prep: implement qc_defer helpers
In reply to Tejun HeoImplement ap->nr_active_links (the number of links with active qcs), ap->excl_link (pointer to link which can be used by ->qc_defer and is cleared when a qc with ATA_QCFLAG_CLEAR_EXCL completes), and ata_link_active().
These can be used by ->qc_defer() to implement proper command exclusion. This set of helpers seem enough for both sil24 (ATAPI exclusion needed) and cmd-switching PMP.
--- drivers/ata/libata-core.c | 22 ++++++++++++++++++++-- drivers/ata/libata-eh.c | 5 +++++ include/linux/libata.h | 8 ++++++++ 3 files changed, 33 insertions(+), 2 deletions(-)
drivers/ata/libata-core.c +20 -2
@@ -1381,6 +1381,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,struct ata_queued_cmd *qc;unsigned int tag, preempted_tag;u32 preempted_sactive, preempted_qc_active; +int preempted_nr_active_links;DECLARE_COMPLETION_ONSTACK (wait);unsigned long flags;unsigned int err_mask;
@@ -1419,9 +1420,11 @@ unsigned ata_exec_internal_sg(struct ata_device *dev, preempted_tag = link->active_tag; preempted_sactive = link->sactive; preempted_qc_active = ap->qc_active; + preempted_nr_active_links = ap->nr_active_links; link->active_tag =ATA_TAG_POISON ; link->sactive =0 ; ap->qc_active =0 ; + ap->nr_active_links =0 ;/* prepare & issue qc */ qc->tf = *tf;
@@ -1500,6 +1503,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev, link->active_tag = preempted_tag; link->sactive = preempted_sactive; ap->qc_active = preempted_qc_active; + ap->nr_active_links = preempted_nr_active_links;/* XXX - Some LLDDs (sata_mv) disable port on command failure. * Until those drivers are fixed, we detect the condition
@@ -5208,10 +5212,19 @@ void __ata_qc_complete(struct ata_queued_cmd *qc)ata_sg_clean (qc);/* command should be marked inactive atomically with qc completion */ -if (qc->tf.protocol ==ATA_PROT_NCQ ) +if (qc->tf.protocol ==ATA_PROT_NCQ ) { link->sactive &= ~(1 << qc->tag); -else +if (!link->sactive) + ap->nr_active_links--; + }else { link->active_tag =ATA_TAG_POISON ; + ap->nr_active_links--; + } + +/* clear exclusive status */ +if (unlikely (qc->flags &ATA_QCFLAG_CLEAR_EXCL && + ap->excl_link == link)) + ap->excl_link =NULL ;/* atapi: mark qc as inactive to prevent the interrupt handler * from completing the command twice later, before the error handler
@@ -5390,9 +5403,14 @@ void ata_qc_issue(struct ata_queued_cmd *qc)if (qc->tf.protocol ==ATA_PROT_NCQ ) {WARN_ON (link->sactive & (1 << qc->tag)); + +if (!link->sactive) + ap->nr_active_links++; link->sactive |=1 << qc->tag; }else {WARN_ON (link->sactive); + + ap->nr_active_links++; link->active_tag = qc->tag; }
drivers/ata/libata-eh.c +5 -0
@@ -316,6 +316,7 @@ void ata_scsi_error(struct Scsi_Host *host) ap->pflags |=ATA_PFLAG_EH_IN_PROGRESS ; ap->pflags &= ~ATA_PFLAG_EH_PENDING ; + ap->excl_link =NULL ;/* don't maintain exclusion over EH */ spin_unlock_irqrestore (ap->lock, flags);
@@ -2336,6 +2337,10 @@ void ata_eh_finish(struct ata_port *ap) } } } + +/* make sure nr_active_links is zero after EH */ +WARN_ON (ap->nr_active_links); + ap->nr_active_links =0 ; }/**
include/linux/libata.h +8 -0
@@ -215,6 +215,7 @@ enum {ATA_QCFLAG_DMAMAP =ATA_QCFLAG_SG |ATA_QCFLAG_SINGLE ,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_FAILED = (1 <<16 ),/* cmd failed and is owned by EH */ ATA_QCFLAG_SENSE_VALID = (1 << 17), /* sense data valid */
@@ -576,11 +577,13 @@ struct ata_port {struct ata_queued_cmd qcmd[ATA_MAX_QUEUE ];unsigned long qc_allocated;unsigned int qc_active; +int nr_active_links;/* #links with active qcs */ struct ata_link link;/* host default link */ int nr_pmp_links;/* nr of available PMP links */ struct ata_link *pmp_link;/* array of PMP links */ +struct ata_link *excl_link;/* for PMP qc exclusion */ struct ata_port_stats stats;struct ata_host *host;
@@ -1093,6 +1096,11 @@ static inline int ata_link_max_devices(const struct ata_link *link)return 1 ; } +static inline int ata_link_active (struct ata_link *link) +{ +return ata_tag_valid (link->active_tag) || link->sactive; +} +static inline struct ata_link *ata_port_first_link (struct ata_port *ap) {if (ap->nr_pmp_links)
Signature · 1 line
1.5.0.3
PATCH 7/12 libata-pmp-prep: implement ATA_LFLAG_NO_SRST, ASSUME_ATA and ASSUME_SEMB
In reply to Tejun HeoSome links on some PMPs locks up on SRST and/or report incorrect device signature. Implement ATA_LFLAG_NO_SRST, ASSUME_ATA and ASSUME_SEMB to handle these quirky links. NO_SRST makes EH avoid SRST. ASSUME_ATA and SEMB forces class code to ATA and SEMB_UNSUP respectively. Note that SEMB isn't currently supported yet so the _UNSUP variant is used.
--- drivers/ata/libata-eh.c | 42 ++++++++++++++++++++++++++++++++---------- include/linux/libata.h | 4 ++++ 2 files changed, 36 insertions(+), 10 deletions(-)
drivers/ata/libata-eh.c +32 -10
@@ -1768,14 +1768,18 @@ static int ata_do_reset(struct ata_link *link, ata_reset_fn_t reset,return 0 ; } -static int ata_eh_followup_srst_needed (int rc,int classify, +static int ata_eh_followup_srst_needed (struct ata_link *link, +int rc,int classify,const unsigned int *classes) { +if (link->flags &ATA_LFLAG_NO_SRST ) +return 0 ;if (rc == -EAGAIN )return 1 ;if (rc !=0 )return 0 ; -if (classify && classes[0 ] ==ATA_DEV_UNKNOWN ) +if (classify && !(link->flags &ATA_LFLAG_ASSUME_CLASS ) && + classes[0 ] ==ATA_DEV_UNKNOWN )return 1 ;return 0 ; }
@@ -1802,7 +1806,8 @@ int ata_eh_reset(struct ata_link *link, int classify,*/ action = ehc->i.action; ehc->i.action &= ~ATA_EH_RESET_MASK ; -if (softreset && (!hardreset || (!sata_set_spd_needed (link) && +if (softreset && (!hardreset || (!(link->flags &ATA_LFLAG_NO_SRST ) && + !sata_set_spd_needed (link) && !(action &ATA_EH_HARDRESET )))) ehc->i.action |=ATA_EH_SOFTRESET ;else
@@ -1865,7 +1870,7 @@ int ata_eh_reset(struct ata_link *link, int classify, rc =ata_do_reset (link, reset, classes, deadline);if (reset == hardreset && -ata_eh_followup_srst_needed (rc, classify, classes)) { +ata_eh_followup_srst_needed (link, rc, classify, classes)) {/* okay, let's do follow-up softreset */ reset = softreset;
@@ -1880,8 +1885,8 @@ int ata_eh_reset(struct ata_link *link, int classify,ata_eh_about_to_do (link,NULL ,ATA_EH_RESET_MASK ); rc =ata_do_reset (link, reset, classes, deadline); -if (rc ==0 && classify && - classes[0 ] ==ATA_DEV_UNKNOWN ) { +if (rc ==0 && classify && classes[0 ] ==ATA_DEV_UNKNOWN && + !(link->flags &ATA_LFLAG_ASSUME_CLASS )) {ata_link_printk (link,KERN_ERR ,"classification failed\n" ); rc = -EINVAL ;
@@ -1889,6 +1894,10 @@ int ata_eh_reset(struct ata_link *link, int classify, } } +/* if we skipped follow-up srst, clear rc */ +if (rc == -EAGAIN ) + rc =0 ; +if (rc && try <ARRAY_SIZE (ata_eh_reset_timeouts)) {unsigned long now = jiffies;
@@ -1913,12 +1922,25 @@ int ata_eh_reset(struct ata_link *link, int classify,if (rc ==0 ) {u32 sstatus; -/* After the reset, the device state is PIO 0 and the -* controller state is undefined. Record the mode. -*/ -ata_link_for_each_dev (dev, link) +ata_link_for_each_dev (dev, link) { +/* After the reset, the device state is PIO 0 +* and the controller state is undefined. +* Record the mode. +*/ dev->pio_mode =XFER_PIO_0 ; +if (ata_link_offline (link)) +continue ; + +/* apply class override and convert UNKNOWN to NONE */ +if (link->flags &ATA_LFLAG_ASSUME_ATA ) + classes[dev->devno] =ATA_DEV_ATA ; +else if (link->flags &ATA_LFLAG_ASSUME_SEMB ) + classes[dev->devno] =ATA_DEV_SEMB_UNSUP ;/* not yet */ +else if (classes[dev->devno] ==ATA_DEV_UNKNOWN ) + classes[dev->devno] =ATA_DEV_NONE ; + } +/* record current link speed */ if (sata_scr_read (link,SCR_STATUS , &sstatus) ==0 ) link->sata_spd = (sstatus >>4 ) &0xf ;
include/linux/libata.h +4 -0
@@ -163,6 +163,10 @@ enum {ATA_LFLAG_HRST_TO_RESUME = (1 <<0 ),/* hardreset to resume link */ ATA_LFLAG_SKIP_D2H_BSY = (1 <<1 ),/* can't wait for the first D2H * Register FIS clearing BSY */ +ATA_LFLAG_NO_SRST = (1 <<2 ),/* avoid softreset */ +ATA_LFLAG_ASSUME_ATA = (1 <<3 ),/* assume ATA class */ +ATA_LFLAG_ASSUME_SEMB = (1 <<4 ),/* assume SEMB class */ +ATA_LFLAG_ASSUME_CLASS =ATA_LFLAG_ASSUME_ATA |ATA_LFLAG_ASSUME_SEMB ,/* struct ata_port flags */ ATA_FLAG_SLAVE_POSS = (1 << 0), /* host supports slave dev */
Signature · 1 line
1.5.0.3
PATCH 8/12 libata-pmp-prep: implement ATA_LFLAG_NO_RETRY
In reply to Tejun HeoSome PMP links are connected to internal pseudo devices which may come and go depending on situation. There's no reason to try hard to recover them. ATA_LFLAG_NO_RETRY tells EH to not retry if the device attached to the link fails.
--- drivers/ata/libata-eh.c | 5 ++++- include/linux/libata.h | 1 + 2 files changed, 5 insertions(+), 1 deletions(-)
drivers/ata/libata-eh.c +4 -1
@@ -2197,7 +2197,10 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,struct ata_eh_context *ehc = &link->eh_context;ata_link_for_each_dev (dev, link) { - ehc->tries[dev->devno] =ATA_EH_DEV_TRIES ; +if (link->flags &ATA_LFLAG_NO_RETRY ) + ehc->tries[dev->devno] =1 ; +else + ehc->tries[dev->devno] =ATA_EH_DEV_TRIES ;/* collect port action mask recorded in dev actions */ ehc->i.action |= ehc->i.dev_action[dev->devno] &
include/linux/libata.h +1 -0
@@ -167,6 +167,7 @@ enum {ATA_LFLAG_ASSUME_ATA = (1 <<3 ),/* assume ATA class */ ATA_LFLAG_ASSUME_SEMB = (1 <<4 ),/* assume SEMB class */ ATA_LFLAG_ASSUME_CLASS =ATA_LFLAG_ASSUME_ATA |ATA_LFLAG_ASSUME_SEMB , +ATA_LFLAG_NO_RETRY = (1 <<5 ),/* don't retry this link */ /* struct ata_port flags */ ATA_FLAG_SLAVE_POSS = (1 << 0), /* host supports slave dev */
Signature · 1 line
1.5.0.3
PATCH 9/12 libata-pmp-prep: implement ATA_LFLAG_DISABLED
In reply to Tejun HeoImplement ATA_LFLAG_DISABLED. The flag indicates the link is disabled due to EH recovery failure. While a link is disabled, no EH action is taken on the link and suspend/resume become noop too.
This will be used by PMP links to manage failed links.
--- drivers/ata/libata-eh.c | 30 +++++++++++++++++++++++++++++- include/linux/libata.h | 3 +++ 2 files changed, 32 insertions(+), 1 deletions(-)
drivers/ata/libata-eh.c +29 -1
@@ -1176,6 +1176,7 @@ static void ata_eh_analyze_serror(struct ata_link *link)struct ata_eh_context *ehc = &link->eh_context;u32 serror = ehc->i.serror;unsigned int err_mask =0 , action =0 ; +u32 hotplug_mask;if (serror &SERR_PERSISTENT ) { err_mask |=AC_ERR_ATA_BUS ;
@@ -1194,7 +1195,20 @@ static void ata_eh_analyze_serror(struct ata_link *link) err_mask |=AC_ERR_SYSTEM ; action |=ATA_EH_HARDRESET ; } -if (serror & (SERR_PHYRDY_CHG |SERR_DEV_XCHG )) + +/* Determine whether a hotplug event has occurred. Both +* SError.N/X are considered hotplug events for enabled or +* host links. For disabled PMP links, only N bit is +* considered as X bit is left at 1 for link plugging. +*/ + hotplug_mask =0 ; + +if (!(link->flags &ATA_LFLAG_DISABLED ) ||ata_is_host_link (link)) + hotplug_mask =SERR_PHYRDY_CHG |SERR_DEV_XCHG ; +else + hotplug_mask =SERR_PHYRDY_CHG ; + +if (serror & hotplug_mask)ata_ehi_hotplugged (&ehc->i); ehc->i.err_mask |= err_mask;
@@ -2089,6 +2103,10 @@ static int ata_eh_skip_recovery(struct ata_link *link)struct ata_eh_context *ehc = &link->eh_context;struct ata_device *dev; +/* skip disabled links */ +if (link->flags &ATA_LFLAG_DISABLED ) +return 1 ; +/* thaw frozen port, resume link and recover failed devices */ if ((link->ap->pflags &ATA_PFLAG_FROZEN ) || (ehc->i.flags &ATA_EHI_RESUME_LINK ) ||ata_link_nr_enabled (link))
@@ -2189,6 +2207,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,struct ata_device *dev;int nr_failed_devs, nr_disabled_devs;int reset, rc; +unsigned long flags;DPRINTK ("ENTER\n" );
@@ -2196,6 +2215,15 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,ata_port_for_each_link (link, ap) {struct ata_eh_context *ehc = &link->eh_context; +/* re-enable link? */ +if (ehc->i.action &ATA_EH_ENABLE_LINK ) { +ata_eh_about_to_do (link,NULL ,ATA_EH_ENABLE_LINK ); +spin_lock_irqsave (ap->lock, flags); + link->flags &= ~ATA_LFLAG_DISABLED ; +spin_unlock_irqrestore (ap->lock, flags); +ata_eh_done (link,NULL ,ATA_EH_ENABLE_LINK ); + } +ata_link_for_each_dev (dev, link) {if (link->flags &ATA_LFLAG_NO_RETRY ) ehc->tries[dev->devno] =1 ;
include/linux/libata.h +3 -0
@@ -168,6 +168,7 @@ enum {ATA_LFLAG_ASSUME_SEMB = (1 <<4 ),/* assume SEMB class */ ATA_LFLAG_ASSUME_CLASS =ATA_LFLAG_ASSUME_ATA |ATA_LFLAG_ASSUME_SEMB ,ATA_LFLAG_NO_RETRY = (1 <<5 ),/* don't retry this link */ +ATA_LFLAG_DISABLED = (1 <<6 ),/* link is disabled */ /* struct ata_port flags */ ATA_FLAG_SLAVE_POSS = (1 << 0), /* host supports slave dev */
@@ -286,6 +287,7 @@ enum {ATA_EH_REVALIDATE = (1 <<0 ),ATA_EH_SOFTRESET = (1 <<1 ),ATA_EH_HARDRESET = (1 <<2 ), +ATA_EH_ENABLE_LINK = (1 <<3 ),ATA_EH_RESET_MASK =ATA_EH_SOFTRESET |ATA_EH_HARDRESET , ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE,
@@ -998,6 +1000,7 @@ static inline void ata_ehi_hotplugged(struct ata_eh_info *ehi) {ata_ehi_schedule_probe (ehi); ehi->flags |=ATA_EHI_HOTPLUGGED ; + ehi->action |=ATA_EH_ENABLE_LINK ; ehi->err_mask |=AC_ERR_ATA_BUS ; }
Signature · 1 line
1.5.0.3
PATCH 10/12 libata-pmp-prep: implement EH fast-fail path
In reply to Tejun HeoIf PMP itself becomes inaccessible while trying to link a downstream link, spending time to recover the downstream link doesn't make any sense. Make EH skip retry and fail fast if -ERESTART is received.
--- drivers/ata/libata-eh.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/ata/libata-eh.c +1 -1
@@ -1912,7 +1912,7 @@ int ata_eh_reset(struct ata_link *link, int classify,if (rc == -EAGAIN ) rc =0 ; -if (rc && try <ARRAY_SIZE (ata_eh_reset_timeouts)) { +if (rc && rc != -ERESTART && try <ARRAY_SIZE (ata_eh_reset_timeouts)) {unsigned long now = jiffies;if (time_before (now, deadline)) {
Signature · 1 line
1.5.0.3
PATCH 11/12 libata-pmp-prep: implement ATA_HORKAGE_SKIP_PM
In reply to Tejun HeoSome pseudo devices fail PM commands unnecessarily aborting system suspend. Implement ATA_HORKAGE_SKIP_PM which makes libata skip PM commands for these devices.
--- drivers/ata/libata-scsi.c | 7 +++++++ include/linux/libata.h | 1 + 2 files changed, 8 insertions(+), 0 deletions(-)
drivers/ata/libata-scsi.c +7 -0
@@ -950,6 +950,13 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) goto invalid_fld;/* LOEJ bit set not supported */ if (((cdb[4 ] >>4 ) &0xf ) !=0 ) goto invalid_fld;/* power conditions not supported */ + +if (ata_device_blacklisted (qc->dev) &ATA_HORKAGE_SKIP_PM ) { +/* the device lacks PM support, finish without doing anything */ + scmd->result =SAM_STAT_GOOD ; +return 1 ; + } +if (cdb[4 ] &0x1 ) { tf->nsect =1 ;/* 1 sector, lba=0 */
include/linux/libata.h +1 -0
@@ -325,6 +325,7 @@ enum {ATA_HORKAGE_NODMA = (1 <<1 ),/* DMA problems */ ATA_HORKAGE_NONCQ = (1 <<2 ),/* Don't use NCQ */ ATA_HORKAGE_MAX_SEC_128 = (1 <<3 ),/* Limit max sects to 128 */ + ATA_HORKAGE_SKIP_PM = (1 << 4), /* Skip PM operations */ }; enum hsm_task_states {
Signature · 1 line
1.5.0.3
PATCH 12/12 libata-pmp-prep: implement sata_async_notification()
In reply to Tejun HeoImplement SATA async notification handler sata_async_notification(). LLDs can call this function when it suspects SDB_NOTIFY has occurred. This function will check SCR_NOTIFICATION if available and schedule proper EH action.
Currently, only PMP notification is handled. The function can be easily extended to cover ATAPI notification later.
--- drivers/ata/libata-core.c | 1 + drivers/ata/libata-eh.c | 49 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/libata.h | 1 + 3 files changed, 51 insertions(+), 0 deletions(-)
drivers/ata/libata-core.c +1 -0
@@ -7051,6 +7051,7 @@ EXPORT_SYMBOL_GPL(ata_port_schedule_eh);EXPORT_SYMBOL_GPL (ata_link_abort);EXPORT_SYMBOL_GPL (ata_port_abort);EXPORT_SYMBOL_GPL (ata_port_freeze); +EXPORT_SYMBOL_GPL (sata_async_notification);EXPORT_SYMBOL_GPL (ata_eh_freeze_port);EXPORT_SYMBOL_GPL (ata_eh_thaw_port);EXPORT_SYMBOL_GPL (ata_eh_qc_complete);
drivers/ata/libata-eh.c +49 -0
55 lines not on this page · raw message
include/linux/libata.h +1 -0
@@ -947,6 +947,7 @@ extern void ata_port_schedule_eh(struct ata_port *ap);extern int ata_link_abort (struct ata_link *link);extern int ata_port_abort (struct ata_port *ap);extern int ata_port_freeze (struct ata_port *ap); +extern int sata_async_notification (struct ata_port *ap);extern void ata_eh_freeze_port (struct ata_port *ap);extern void ata_eh_thaw_port (struct ata_port *ap);
Signature · 1 line
1.5.0.3
Quoted 20 lines · Tejun Heo
Hello, all.
This is the fourth take of libata-pmp-prep patchset. This patchset contains 12 patches implementing various stuff needed for PMP.
#01 : add PMP related constants
#02-04 : various small stuff
#05-06 :qc_defermechanism implementation
#07-11 : link/device quirks and EH fast-fail path - things needed to
handle quirky PMP fan-out links / pseudo devices.
#12 : SATA SDB notify handlerChanges from the last take[L] are.
* PMP related constants patch moved here from pmp patchset
*qc_deferCLEAR_EXCLfixed to clearexcl_linkiff it points to self
* addition of various quirks/special case handling vital for supporting first-gen PMP chips
* generalized SDB notify handling
Quoted 5 lines
This patchset is against
libata-dev#upstream (
4e1ae96828f6cee7b89ab8ca474c150fe211afd8)
+ [1] misc-updates patchset
+ [2] libata-link patchset, take 4
seems generally OK to me