libata: implement ata_link, take 4
Subsystems (2)
PATCH 2/4 libata: implement ata_link, take 4
To: Jeff Garzik <[email protected]>, Alan Cox <[email protected]>, [email protected], Forrest Zhao <[email protected]>
Subject: [PATCHSET 2/4] libata: implement ata_link, take 4
Hello, all.
This is the fourth take of implement ata_link patchset. This patchset contains 16 patches which can be categorized as follows.
#01-02: prep
#03-04: implement ata_link
#05-08: make libata deal with link instead of port #09-11: misc link stuff (link init, reset_tries, ata_link_abort()) #12-16: add ap->pmp_link[] and update libata to deal with multiple
links
ata_link abstracts PHY and sits between ata_port and ata_device. The following attributes are moved to ata_link from ata_port.
- active command state (active_tag, sactive)
- [hw_]sata_spd_limit
- eh_info and eh_context
- device array
With above and a few extra fields, a link can handle attached devices including qc management and EH/hotplug. This patchset makes libata ready to handle PMP links.
Changes from the last take[L] are.
* updated to fit new #upstream
* SError failure handling updated and moved to misc-updates patchset
* ata_dev_configure() update is unnecessary now and dropped
This patchset is against
libata-dev#upstream (4e1ae96828f6cee7b89ab8ca474c150fe211afd8)
+ [1] misc-updates patchset
Thanks.
--
tejun
[L] http://thread.gmane.org/gmane.linux.ide/13478
[1] http://thread.gmane.org/gmane.linux.ide/20081
PATCH 1/16 libata-link: separate out ata_eh_handle_dev_fail()
Separate out ata_eh_handle_dev_fail() from ata_eh_recover(). This is in preparation of ata_link and PMP support.
--- drivers/ata/libata-eh.c | 96 +++++++++++++++++++++++++--------------------- 1 files changed, 52 insertions(+), 44 deletions(-)
drivers/ata/libata-eh.c +52 -44
@@ -2008,6 +2008,57 @@ static int ata_eh_skip_recovery(struct ata_port *ap)return 1 ; } +static void ata_eh_handle_dev_fail (struct ata_device *dev,int err) +{ +struct ata_port *ap = dev->ap; +struct ata_eh_context *ehc = &ap->eh_context; + + ehc->tries[dev->devno]--; + +switch (err) { +case -ENODEV : +/* device missing or wrong IDENTIFY data, schedule probing */ + ehc->i.probe_mask |= (1 << dev->devno); +case -EINVAL : +/* give it just one more chance */ + ehc->tries[dev->devno] =min (ehc->tries[dev->devno],1 ); +case -EIO : +if (ehc->tries[dev->devno] ==1 ) { +/* This is the last chance, better to slow +* down than lose it. +*/ +sata_down_spd_limit (ap); +ata_down_xfermask_limit (dev,ATA_DNXFER_PIO ); + } + } + +if (ata_dev_enabled (dev) && !ehc->tries[dev->devno]) { +/* disable device if it has used up all its chances */ +ata_dev_disable (dev); + +/* detach if offline */ +if (ata_port_offline (ap)) +ata_eh_detach_dev (dev); + +/* probe if requested */ +if ((ehc->i.probe_mask & (1 << dev->devno)) && + !(ehc->did_probe_mask & (1 << dev->devno))) { +ata_eh_detach_dev (dev); +ata_dev_init (dev); + + ehc->tries[dev->devno] =ATA_EH_DEV_TRIES ; + ehc->did_probe_mask |= (1 << dev->devno); + ehc->i.action |=ATA_EH_SOFTRESET ; + } + }else { +/* soft didn't work? be haaaaard */ +if (ehc->i.flags &ATA_EHI_DID_RESET ) + ehc->i.action |=ATA_EH_HARDRESET ; +else + ehc->i.action |=ATA_EH_SOFTRESET ; + } +} +/** * ata_eh_recover - recover host port after error * @ap: host port to recover
@@ -2108,50 +2159,7 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset, goto out; dev_fail: - ehc->tries[dev->devno]--; - -switch (rc) { -case -ENODEV : -/* device missing or wrong IDENTIFY data, schedule probing */ - ehc->i.probe_mask |= (1 << dev->devno); -case -EINVAL : -/* give it just one more chance */ - ehc->tries[dev->devno] =min (ehc->tries[dev->devno],1 ); -case -EIO : -if (ehc->tries[dev->devno] ==1 ) { -/* This is the last chance, better to slow -* down than lose it. -*/ -sata_down_spd_limit (ap); -ata_down_xfermask_limit (dev,ATA_DNXFER_PIO ); - } - } - -if (ata_dev_enabled (dev) && !ehc->tries[dev->devno]) { -/* disable device if it has used up all its chances */ -ata_dev_disable (dev); - -/* detach if offline */ -if (ata_port_offline (ap)) -ata_eh_detach_dev (dev); - -/* probe if requested */ -if ((ehc->i.probe_mask & (1 << dev->devno)) && - !(ehc->did_probe_mask & (1 << dev->devno))) { -ata_eh_detach_dev (dev); -ata_dev_init (dev); - - ehc->tries[dev->devno] =ATA_EH_DEV_TRIES ; - ehc->did_probe_mask |= (1 << dev->devno); - ehc->i.action |=ATA_EH_SOFTRESET ; - } - }else { -/* soft didn't work? be haaaaard */ -if (ehc->i.flags &ATA_EHI_DID_RESET ) - ehc->i.action |=ATA_EH_HARDRESET ; -else - ehc->i.action |=ATA_EH_SOFTRESET ; - } +ata_eh_handle_dev_fail (dev, rc);if (ata_port_nr_enabled (ap)) { ata_port_printk(ap, KERN_WARNING, "failed to recover some "
Signature · 1 line
1.5.0.3
Re: [PATCH 01/16] libata-link: separate out ata_eh_handle_dev_fail()
Quoted 7 lines · Tejun Heo
Separate out
ata_eh_handle_dev_fail()fromata_eh_recover(). This is in preparation ofata_linkand PMP support.Signed-off-by Tejun Heo <[email protected]>--- drivers/ata/libata-eh.c | 96 +++++++++++++++++++++++++--------------------- 1 files changed, 52 insertions(+), 44 deletions(-)
applied 1-2
PATCH 2/16 libata-link: add PMP related ATA constants
In reply to Tejun HeoAdd Port Multiplier related ATA constants and macros. Some of these will be used by ata_link implementation.
--- include/linux/ata.h | 29 +++++++++++++++++++++++++++++ 1 files changed, 29 insertions(+), 0 deletions(-)
include/linux/ata.h +29 -0
@@ -164,6 +164,8 @@ enum {ATA_CMD_SET_MAX =0xF9 ,ATA_CMD_SET_MAX_EXT =0x37 ,ATA_CMD_READ_LOG_EXT =0x2f , +ATA_CMD_PMP_READ =0xE4 , +ATA_CMD_PMP_WRITE =0xE8 ,/* READ_LOG_EXT pages */ ATA_LOG_SATA_NCQ = 0x10,
@@ -212,6 +214,28 @@ enum {0=to device, 1=to host */ ATAPI_CDB_LEN =16 , +/* PMP stuff */ +SATA_PMP_MAX_PORTS =15 , +SATA_PMP_CTRL_PORT =15 , + +SATA_PMP_GSCR_DWORDS =128 , +SATA_PMP_GSCR_PROD_ID =0 , +SATA_PMP_GSCR_REV =1 , +SATA_PMP_GSCR_PORT_INFO =2 , +SATA_PMP_GSCR_ERROR =32 , +SATA_PMP_GSCR_ERROR_EN =33 , +SATA_PMP_GSCR_FEAT =64 , +SATA_PMP_GSCR_FEAT_EN =96 , + +SATA_PMP_PSCR_STATUS =0 , +SATA_PMP_PSCR_ERROR =1 , +SATA_PMP_PSCR_CONTROL =2 , + +SATA_PMP_FEAT_BIST = (1 <<0 ), +SATA_PMP_FEAT_PMREQ = (1 <<1 ), +SATA_PMP_FEAT_DYNSSC = (1 <<2 ), +SATA_PMP_FEAT_NOTIFY = (1 <<3 ), +/* cable types */ ATA_CBL_NONE =0 , ATA_CBL_PATA40 = 1,
@@ -418,4 +442,9 @@ static inline int lba_48_ok(u64 block, u32 n_block) return ((block + n_block - 1) < ((u64)1 << 48)) && (n_block <= 65536); } +#define sata_pmp_gscr_vendor (gscr) ((gscr)[SATA_PMP_GSCR_PROD_ID] & 0xffff) +#define sata_pmp_gscr_devid (gscr) ((gscr)[SATA_PMP_GSCR_PROD_ID] >> 16) +#define sata_pmp_gscr_rev (gscr) (((gscr)[SATA_PMP_GSCR_REV] >> 8) & 0xff) +#define sata_pmp_gscr_ports (gscr) ((gscr)[SATA_PMP_GSCR_PORT_INFO] & 0xf) +#endif /* __LINUX_ATA_H__ */
Signature · 1 line
1.5.0.3
PATCH 3/16 libata-link: introduce ata_link
In reply to Tejun HeoIntroduce ata_link. It abstracts PHY and sits between ata_port and ata_device. This new level of abstraction is necessary to support SATA Port Multiplier, which basically adds a bunch of links (PHYs) to a ATA host port. Fields related to command execution, spd_limit and EH are per-link and thus moved to ata_link.
This patch only defines the host link. Multiple link handling will be added later. Also, a lot of ap->link derefences are added but many of them will be removed as each part is converted to deal directly with ata_link instead of ata_port.
This patch introduces no behavior change.
--- drivers/ata/ahci.c | 18 +++--- drivers/ata/ata_generic.c | 2 +- drivers/ata/libata-acpi.c | 21 +++--- drivers/ata/libata-core.c | 157 ++++++++++++++++++++++-------------------- drivers/ata/libata-eh.c | 100 ++++++++++++++------------- drivers/ata/libata-scsi.c | 41 ++++++----- drivers/ata/libata-sff.c | 4 +- drivers/ata/pata_it821x.c | 4 +- drivers/ata/pata_ixp4xx_cf.c | 4 +- drivers/ata/pata_legacy.c | 4 +- drivers/ata/pata_optidma.c | 4 +- drivers/ata/pata_pcmcia.c | 4 +- drivers/ata/pata_pdc2027x.c | 2 +- drivers/ata/pata_platform.c | 2 +- drivers/ata/pata_qdi.c | 2 +- drivers/ata/pata_rz1000.c | 2 +- drivers/ata/pata_scc.c | 2 +- drivers/ata/pata_sis.c | 2 +- drivers/ata/pata_winbond.c | 2 +- drivers/ata/pdc_adma.c | 4 +- drivers/ata/sata_inic162x.c | 7 +- drivers/ata/sata_mv.c | 6 +- drivers/ata/sata_nv.c | 26 ++++---- drivers/ata/sata_promise.c | 4 +- drivers/ata/sata_qstor.c | 4 +- drivers/ata/sata_sil.c | 14 ++-- drivers/ata/sata_sil24.c | 12 ++-- drivers/ata/sata_sx4.c | 4 +- drivers/ata/sata_via.c | 2 +- drivers/ata/sata_vsc.c | 2 +- include/linux/libata.h | 40 +++++++---- 31 files changed, 263 insertions(+), 239 deletions(-)
drivers/ata/ahci.c +9 -9
@@ -981,7 +981,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class,/* restart engine */ ahci_start_engine (ap); -ata_tf_init (ap->device, &tf); +ata_tf_init (ap->link.device, &tf); fis = pp->cmd_tbl;/* issue the first D2H Register FIS */
@@ -1055,7 +1055,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class,ahci_stop_engine (ap);/* clear D2H reception area to properly wait for D2H FIS */ -ata_tf_init (ap->device, &tf); +ata_tf_init (ap->link.device, &tf); tf.command =0x80 ;ata_tf_to_fis (&tf, d2h_fis,0 );
@@ -1082,7 +1082,7 @@ static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class,ahci_stop_engine (ap); - rc =sata_port_hardreset (ap,sata_ehc_deb_timing (&ap->eh_context), + rc =sata_port_hardreset (ap,sata_ehc_deb_timing (&ap->link.eh_context), deadline);/* vt8251 needs SError cleared for the port to operate */
@@ -1201,7 +1201,7 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc)static void ahci_error_intr (struct ata_port *ap,u32 irq_stat) {struct ahci_port_priv *pp = ap->private_data; -struct ata_eh_info *ehi = &ap->eh_info; +struct ata_eh_info *ehi = &ap->link.eh_info;unsigned int err_mask =0 , action =0 ;struct ata_queued_cmd *qc;u32 serror;
@@ -1255,7 +1255,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat) ehi->serror |= serror; ehi->action |= action; - qc =ata_qc_from_tag (ap, ap->active_tag); + qc =ata_qc_from_tag (ap, ap->link.active_tag);if (qc) qc->err_mask |= err_mask;else
@@ -1270,7 +1270,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)static void ahci_port_intr (struct ata_port *ap) {void __iomem *port_mmio = ap->ioaddr.cmd_addr; -struct ata_eh_info *ehi = &ap->eh_info; +struct ata_eh_info *ehi = &ap->link.eh_info;struct ahci_port_priv *pp = ap->private_data;u32 status, qc_active;int rc, known_irq =0 ;
@@ -1283,7 +1283,7 @@ static void ahci_port_intr(struct ata_port *ap)return ; } -if (ap->sactive) +if (ap->link.sactive) qc_active =readl (port_mmio +PORT_SCR_ACT );else qc_active =readl (port_mmio +PORT_CMD_ISSUE );
@@ -1303,7 +1303,7 @@ static void ahci_port_intr(struct ata_port *ap)/* if !NCQ, ignore. No modern ATA device has broken HSM * implementation for non-NCQ commands. */ -if (!ap->sactive) +if (!ap->link.sactive)return ;if (status &PORT_IRQ_D2H_REG_FIS ) {
@@ -1356,7 +1356,7 @@ static void ahci_port_intr(struct ata_port *ap)if (!known_irq)ata_port_printk (ap,KERN_INFO ,"spurious interrupt " "(irq_stat 0x%x active_tag 0x%x sactive 0x%x)\n" , - status, ap->active_tag, ap->sactive); + status, ap->link.active_tag, ap->link.sactive); }static void ahci_irq_clear (struct ata_port *ap)
drivers/ata/ata_generic.c +1 -1
@@ -53,7 +53,7 @@ static int generic_set_mode(struct ata_port *ap, struct ata_device **unused) dma_enabled =ioread8 (ap->ioaddr.bmdma_addr +ATA_DMA_CMD );for (i =0 ; i <ATA_MAX_DEVICES ; i++) { -struct ata_device *dev = &ap->device[i]; +struct ata_device *dev = &ap->link.device[i];if (ata_dev_enabled (dev)) {/* We don't really care */ dev->pio_mode =XFER_PIO_0 ;
drivers/ata/libata-acpi.c +11 -10
@@ -44,7 +44,8 @@ static void ata_acpi_associate_sata_port(struct ata_port *ap) {acpi_integer adr =SATA_ADR (ap->port_no,NO_PORT_MULT ); - ap->device->acpi_handle =acpi_get_child (ap->host->acpi_handle, adr); + ap->link.device->acpi_handle = +acpi_get_child (ap->host->acpi_handle, adr); }static void ata_acpi_associate_ide_port (struct ata_port *ap)
@@ -60,7 +61,7 @@ static void ata_acpi_associate_ide_port(struct ata_port *ap) max_devices++;for (i =0 ; i < max_devices; i++) { -struct ata_device *dev = &ap->device[i]; +struct ata_device *dev = &ap->link.device[i]; dev->acpi_handle =acpi_get_child (ap->acpi_handle, i); }
@@ -182,10 +183,10 @@ static int ata_acpi_stm(const struct ata_port *ap, struct ata_acpi_gtm *stm)/* Buffers for id may need byteswapping ? */ in_params[1 ].type =ACPI_TYPE_BUFFER ; in_params[1 ].buffer.length =512 ; - in_params[1 ].buffer.pointer = (u8 *)ap->device[0 ].id; + in_params[1 ].buffer.pointer = (u8 *)ap->link.device[0 ].id; in_params[2 ].type =ACPI_TYPE_BUFFER ; in_params[2 ].buffer.length =512 ; - in_params[2 ].buffer.pointer = (u8 *)ap->device[1 ].id; + in_params[2 ].buffer.pointer = (u8 *)ap->link.device[1 ].id; input.count =3 ; input.pointer = in_params;
@@ -226,7 +227,7 @@ static int ata_acpi_stm(const struct ata_port *ap, struct ata_acpi_gtm *stm)static int ata_dev_get_GTF (struct ata_device *dev,struct ata_acpi_gtf **gtf,void **ptr_to_free) { -struct ata_port *ap = dev->ap; +struct ata_port *ap = dev->link->ap;acpi_status status;struct acpi_buffer output;union acpi_object *out_obj;
@@ -320,7 +321,7 @@ static int ata_dev_get_GTF(struct ata_device *dev, struct ata_acpi_gtf **gtf,static int taskfile_load_raw (struct ata_device *dev,const struct ata_acpi_gtf *gtf) { -struct ata_port *ap = dev->ap; +struct ata_port *ap = dev->link->ap;struct ata_taskfile tf, rtf;unsigned int err_mask;
@@ -424,7 +425,7 @@ static int ata_acpi_exec_tfs(struct ata_device *dev)*/ static int ata_acpi_push_id (struct ata_device *dev) { -struct ata_port *ap = dev->ap; +struct ata_port *ap = dev->link->ap;int err;acpi_status status;struct acpi_object_list input;
@@ -519,7 +520,7 @@ void ata_acpi_on_resume(struct ata_port *ap)/* schedule _GTF */ for (i =0 ; i <ATA_MAX_DEVICES ; i++) - ap->device[i].flags |=ATA_DFLAG_ACPI_PENDING ; + ap->link.device[i].flags |=ATA_DFLAG_ACPI_PENDING ; }/**
@@ -538,8 +539,8 @@ void ata_acpi_on_resume(struct ata_port *ap)*/ int ata_acpi_on_devcfg (struct ata_device *dev) { -struct ata_port *ap = dev->ap; -struct ata_eh_context *ehc = &ap->eh_context; +struct ata_port *ap = dev->link->ap; +struct ata_eh_context *ehc = &ap->link.eh_context;int acpi_sata = ap->flags &ATA_FLAG_ACPI_SATA ;int rc;
drivers/ata/libata-core.c +83 -74
482 lines not on this page · raw message
drivers/ata/libata-eh.c +51 -49
335 lines not on this page · raw message
drivers/ata/libata-scsi.c +21 -20
134 lines not on this page · raw message
drivers/ata/libata-sff.c +2 -2
@@ -440,7 +440,7 @@ void ata_bmdma_drive_eh(struct ata_port *ap, ata_prereset_fn_t prereset,unsigned long flags;int thaw =0 ; - qc =__ata_qc_from_tag (ap, ap->active_tag); + qc =__ata_qc_from_tag (ap, ap->link.active_tag);if (qc && !(qc->flags &ATA_QCFLAG_FAILED )) qc =NULL ;
@@ -1123,7 +1123,7 @@ unsigned long ata_pci_default_filter(struct ata_device *adev, unsigned long xfer/* Filter out DMA modes if the device has been configured by the BIOS as PIO only */ -if (adev->ap->ioaddr.bmdma_addr ==0 ) +if (adev->link->ap->ioaddr.bmdma_addr ==0 ) xfer_mask &= ~(ATA_MASK_MWDMA |ATA_MASK_UDMA );return xfer_mask; }
drivers/ata/pata_it821x.c +2 -2
@@ -391,7 +391,7 @@ static void it821x_passthru_dev_select(struct ata_port *ap, {struct it821x_dev *itdev = ap->private_data;if (itdev && device != itdev->last_device) { -struct ata_device *adev = &ap->device[device]; +struct ata_device *adev = &ap->link.device[device];it821x_program (ap, adev, itdev->pio[adev->devno]); itdev->last_device = device; }
@@ -464,7 +464,7 @@ static int it821x_smart_set_mode(struct ata_port *ap, struct ata_device **unusedint i;for (i =0 ; i <ATA_MAX_DEVICES ; i++) { -struct ata_device *dev = &ap->device[i]; +struct ata_device *dev = &ap->link.device[i];if (ata_dev_enabled (dev)) {/* We don't really care */ dev->pio_mode =XFER_PIO_0 ;
drivers/ata/pata_ixp4xx_cf.c +2 -2
@@ -31,7 +31,7 @@ static int ixp4xx_set_mode(struct ata_port *ap, struct ata_device **error)int i;for (i =0 ; i <ATA_MAX_DEVICES ; i++) { -struct ata_device *dev = &ap->device[i]; +struct ata_device *dev = &ap->link.device[i];if (ata_dev_enabled (dev)) {ata_dev_printk (dev,KERN_INFO ,"configured for PIO0\n" ); dev->pio_mode =XFER_PIO_0 ;
@@ -49,7 +49,7 @@ static void ixp4xx_mmio_data_xfer(struct ata_device *adev, unsigned char *buf,unsigned int i;unsigned int words = buflen >>1 ;u16 *buf16 = (u16 *) buf; -struct ata_port *ap = adev->ap; +struct ata_port *ap = adev->link->ap;void __iomem *mmio = ap->ioaddr.data_addr;struct ixp4xx_pata_data *data = ap->host->dev->platform_data;
drivers/ata/pata_legacy.c +2 -2
@@ -112,7 +112,7 @@ static int legacy_set_mode(struct ata_port *ap, struct ata_device **unused)int i;for (i =0 ; i <ATA_MAX_DEVICES ; i++) { -struct ata_device *dev = &ap->device[i]; +struct ata_device *dev = &ap->link.device[i];if (ata_dev_enabled (dev)) {ata_dev_printk (dev,KERN_INFO ,"configured for PIO\n" ); dev->pio_mode =XFER_PIO_0 ;
@@ -256,7 +256,7 @@ static void pdc20230_set_piomode(struct ata_port *ap, struct ata_device *adev)static void pdc_data_xfer_vlb (struct ata_device *adev,unsigned char *buf,unsigned int buflen,int write_data) { -struct ata_port *ap = adev->ap; +struct ata_port *ap = adev->link->ap;int slop = buflen &3 ;unsigned long flags;
drivers/ata/pata_optidma.c +2 -2
@@ -340,8 +340,8 @@ static int optidma_set_mode(struct ata_port *ap, struct ata_device **r_failed)pci_read_config_byte (pdev,0x43 , &r); r &= (0x0F << nybble); - r |= (optidma_make_bits43 (&ap->device[0 ]) + - (optidma_make_bits43 (&ap->device[0 ]) <<2 )) << nybble; + r |= (optidma_make_bits43 (&ap->link.device[0 ]) + + (optidma_make_bits43 (&ap->link.device[0 ]) <<2 )) << nybble;pci_write_config_byte (pdev,0x43 , r); }return rc;
drivers/ata/pata_pcmcia.c +2 -2
@@ -67,8 +67,8 @@ struct ata_pcmcia_info {static int pcmcia_set_mode (struct ata_port *ap,struct ata_device **r_failed_dev) { -struct ata_device *master = &ap->device[0 ]; -struct ata_device *slave = &ap->device[1 ]; +struct ata_device *master = &ap->link.device[0 ]; +struct ata_device *slave = &ap->link.device[1 ];if (!ata_dev_enabled (master) || !ata_dev_enabled (slave))return ata_do_set_mode (ap, r_failed_dev);
drivers/ata/pata_pdc2027x.c +1 -1
@@ -486,7 +486,7 @@ static int pdc2027x_set_mode(struct ata_port *ap, struct ata_device **r_failed)return i;for (i =0 ; i <ATA_MAX_DEVICES ; i++) { -struct ata_device *dev = &ap->device[i]; +struct ata_device *dev = &ap->link.device[i];if (ata_dev_enabled (dev)) {
drivers/ata/pata_platform.c +1 -1
@@ -35,7 +35,7 @@ static int pata_platform_set_mode(struct ata_port *ap, struct ata_device **unuseint i;for (i =0 ; i <ATA_MAX_DEVICES ; i++) { -struct ata_device *dev = &ap->device[i]; +struct ata_device *dev = &ap->link.device[i];if (ata_dev_enabled (dev)) {/* We don't really care */
drivers/ata/pata_qdi.c +1 -1
@@ -126,7 +126,7 @@ static unsigned int qdi_qc_issue_prot(struct ata_queued_cmd *qc)static void qdi_data_xfer (struct ata_device *adev,unsigned char *buf,unsigned int buflen,int write_data) { -struct ata_port *ap = adev->ap; +struct ata_port *ap = adev->link->ap;int slop = buflen &3 ;if (ata_id_has_dword_io (adev->id)) {
drivers/ata/pata_rz1000.c +1 -1
@@ -39,7 +39,7 @@ static int rz1000_set_mode(struct ata_port *ap, struct ata_device **unused)int i;for (i =0 ; i <ATA_MAX_DEVICES ; i++) { -struct ata_device *dev = &ap->device[i]; +struct ata_device *dev = &ap->link.device[i];if (ata_dev_enabled (dev)) {/* We don't really care */ dev->pio_mode =XFER_PIO_0 ;
drivers/ata/pata_scc.c +1 -1
@@ -758,7 +758,7 @@ static u8 scc_bmdma_status (struct ata_port *ap)static void scc_data_xfer (struct ata_device *adev,unsigned char *buf,unsigned int buflen,int write_data) { -struct ata_port *ap = adev->ap; +struct ata_port *ap = adev->link->ap;unsigned int words = buflen >>1 ;unsigned int i;u16 *buf16 = (u16 *) buf;
drivers/ata/pata_sis.c +1 -1
@@ -82,7 +82,7 @@ static int sis_short_ata40(struct pci_dev *dev)static int sis_old_port_base (struct ata_device *adev) { -return 0x40 + (4 * adev->ap->port_no) + (2 * adev->devno); +return 0x40 + (4 * adev->link->ap->port_no) + (2 * adev->devno); }/**
drivers/ata/pata_winbond.c +1 -1
@@ -94,7 +94,7 @@ static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev)static void winbond_data_xfer (struct ata_device *adev,unsigned char *buf,unsigned int buflen,int write_data) { -struct ata_port *ap = adev->ap; +struct ata_port *ap = adev->link->ap;int slop = buflen &3 ;if (ata_id_has_dword_io (adev->id)) {
drivers/ata/pdc_adma.c +2 -2
@@ -464,7 +464,7 @@ static inline unsigned int adma_intr_pkt(struct ata_host *host) pp = ap->private_data;if (!pp || pp->state != adma_state_pkt)continue ; - qc =ata_qc_from_tag (ap, ap->active_tag); + qc =ata_qc_from_tag (ap, ap->link.active_tag);if (qc && (!(qc->tf.flags &ATA_TFLAG_POLLING ))) {if ((status & (aPERR | aPSD | aUIRQ))) qc->err_mask |=AC_ERR_OTHER ;
@@ -489,7 +489,7 @@ static inline unsigned int adma_intr_mmio(struct ata_host *host)struct adma_port_priv *pp = ap->private_data;if (!pp || pp->state != adma_state_mmio)continue ; - qc =ata_qc_from_tag (ap, ap->active_tag); + qc =ata_qc_from_tag (ap, ap->link.active_tag);if (qc && (!(qc->tf.flags &ATA_TFLAG_POLLING ))) {/* check main status, clearing INTRQ */
drivers/ata/sata_inic162x.c +4 -3
@@ -285,7 +285,7 @@ static void inic_irq_clear(struct ata_port *ap)static void inic_host_intr (struct ata_port *ap) {void __iomem *port_base =inic_port_base (ap); -struct ata_eh_info *ehi = &ap->eh_info; +struct ata_eh_info *ehi = &ap->link.eh_info;u8 irq_stat;/* fetch and clear irq */
@@ -293,7 +293,8 @@ static void inic_host_intr(struct ata_port *ap)writeb (irq_stat, port_base +PORT_IRQ_STAT );if (likely (!(irq_stat &PIRQ_ERR ))) { -struct ata_queued_cmd *qc =ata_qc_from_tag (ap, ap->active_tag); +struct ata_queued_cmd *qc = +ata_qc_from_tag (ap, ap->link.active_tag);if (unlikely (!qc || (qc->tf.flags &ATA_TFLAG_POLLING ))) {ata_chk_status (ap);/* clear ATA interrupt */
@@ -421,7 +422,7 @@ static int inic_hardreset(struct ata_port *ap, unsigned int *class, {void __iomem *port_base =inic_port_base (ap);void __iomem *idma_ctl = port_base +PORT_IDMA_CTL ; -const unsigned long *timing =sata_ehc_deb_timing (&ap->eh_context); +const unsigned long *timing =sata_ehc_deb_timing (&ap->link.eh_context);u16 val;int rc;
drivers/ata/sata_mv.c +3 -3
@@ -1443,7 +1443,7 @@ static void mv_host_intr(struct ata_host *host, u32 relevant, unsigned int hc) }if (handled) { - qc =ata_qc_from_tag (ap, ap->active_tag); + qc =ata_qc_from_tag (ap, ap->link.active_tag);if (qc && (qc->flags &ATA_QCFLAG_ACTIVE )) {VPRINTK ("port %u IRQ found for qc, " "ata_status 0x%x\n" , port,ata_status);
@@ -1969,7 +1969,7 @@ static void __mv_phy_reset(struct ata_port *ap, int can_sleep)struct mv_host_priv *hpriv = ap->host->private_data;void __iomem *port_mmio =mv_ap_base (ap);struct ata_taskfile tf; -struct ata_device *dev = &ap->device[0 ]; +struct ata_device *dev = &ap->link.device[0 ];unsigned long timeout;int retry =5 ;u32 sstatus;
@@ -2091,7 +2091,7 @@ static void mv_eng_timeout(struct ata_port *ap)DPRINTK ("All regs @ start of eng_timeout\n" );mv_dump_all_regs (mmio, ap->port_no,to_pci_dev (ap->host->dev)); - qc =ata_qc_from_tag (ap, ap->active_tag); + qc =ata_qc_from_tag (ap, ap->link.active_tag);printk (KERN_ERR "mmio_base %p ap %p qc %p scsi_cmnd %p &cmnd %p\n" , mmio, ap, qc, qc->scsicmd, &qc->scsicmd->cmnd);
drivers/ata/sata_nv.c +13 -13
@@ -593,7 +593,7 @@ static int nv_adma_slave_config(struct scsi_device *sdev)/* Not a proper libata device, ignore */ return rc; -if (ap->device[sdev->id].class ==ATA_DEV_ATAPI ) { +if (ap->link.device[sdev->id].class ==ATA_DEV_ATAPI ) {/* * NVIDIA reports that ADMA mode does not support ATAPI commands. * Therefore ATAPI commands are sent through the legacy interface.
@@ -710,7 +710,7 @@ static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err) flags & (NV_CPB_RESP_ATA_ERR | NV_CPB_RESP_CMD_ERR | NV_CPB_RESP_CPB_ERR)))) { -struct ata_eh_info *ehi = &ap->eh_info; +struct ata_eh_info *ehi = &ap->link.eh_info;int freeze =0 ;ata_ehi_clear_desc (ehi);
@@ -746,7 +746,7 @@ static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err)DPRINTK ("Completing qc from tag %d\n" ,cpb_num);ata_qc_complete (qc); }else { -struct ata_eh_info *ehi = &ap->eh_info; +struct ata_eh_info *ehi = &ap->link.eh_info;/* Notifier bits set without a command may indicate the drive is misbehaving. Raise host state machine violation on this condition. */
@@ -763,7 +763,7 @@ static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err)static int nv_host_intr (struct ata_port *ap,u8 irq_stat) { -struct ata_queued_cmd *qc =ata_qc_from_tag (ap, ap->active_tag); +struct ata_queued_cmd *qc =ata_qc_from_tag (ap, ap->link.active_tag);/* freeze if hotplugged */ if (unlikely (irq_stat & (NV_INT_ADDED |NV_INT_REMOVED ))) {
@@ -816,7 +816,7 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)if (pp->flags &NV_ADMA_PORT_REGISTER_MODE ) {u8 irq_stat =readb (host->iomap[NV_MMIO_BAR ] +NV_INT_STATUS_CK804 ) >> (NV_INT_PORT_SHIFT * i); -if (ata_tag_valid (ap->active_tag)) +if (ata_tag_valid (ap->link.active_tag))/** NV_INT_DEV indication seems unreliable at times at least in ADMA mode. Force it on always when a command is active, to prevent losing interrupts. */
@@ -851,7 +851,7 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance) NV_ADMA_STAT_HOTUNPLUG | NV_ADMA_STAT_TIMEOUT | NV_ADMA_STAT_SERROR))) { -struct ata_eh_info *ehi = &ap->eh_info; +struct ata_eh_info *ehi = &ap->link.eh_info;ata_ehi_clear_desc (ehi);ata_ehi_push_desc (ehi,"<ADMA status 0x%08x" , status );
@@ -877,10 +877,10 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)u32 check_commands;int pos, error =0 ; -if (ata_tag_valid (ap->active_tag)) - check_commands =1 << ap->active_tag; +if (ata_tag_valid (ap->link.active_tag)) + check_commands =1 << ap->link.active_tag;else - check_commands = ap->sactive; + check_commands = ap->link.sactive;/** Check CPBs for completed commands */ while ((pos =ffs (check_commands)) && !error) {
@@ -1331,7 +1331,7 @@ static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance) !(ap->flags & ATA_FLAG_DISABLED)) {struct ata_queued_cmd *qc; - qc =ata_qc_from_tag (ap, ap->active_tag); + qc =ata_qc_from_tag (ap, ap->link.active_tag);if (qc && (!(qc->tf.flags &ATA_TFLAG_POLLING ))) handled +=ata_host_intr (ap, qc);else
@@ -1483,7 +1483,7 @@ static void nv_adma_error_handler(struct ata_port *ap)int i;u16 tmp; -if (ata_tag_valid (ap->active_tag) || ap->sactive) { +if (ata_tag_valid (ap->link.active_tag) || ap->link.sactive) {u32 notifier =readl (mmio +NV_ADMA_NOTIFIER );u32 notifier_error =readl (mmio +NV_ADMA_NOTIFIER_ERROR );u32 gen_ctl =readl (pp->gen_block +NV_ADMA_GEN_CTL );
@@ -1499,8 +1499,8 @@ static void nv_adma_error_handler(struct ata_port *ap)for ( i=0 ;i<NV_ADMA_MAX_CPBS ;i++) {struct nv_adma_cpb *cpb = &pp->cpb[i]; -if ( (ata_tag_valid (ap->active_tag) && i == ap->active_tag) || - ap->sactive & (1 << i) ) +if ( (ata_tag_valid (ap->link.active_tag) && i == ap->link.active_tag) || + ap->link.sactive & (1 << i) )ata_port_printk (ap,KERN_ERR ,"CPB %d: ctl_flags 0x%x, resp_flags 0x%x\n" , i, cpb->ctl_flags, cpb->resp_flags);
drivers/ata/sata_promise.c +2 -2
@@ -631,7 +631,7 @@ static void pdc_post_internal_cmd(struct ata_queued_cmd *qc)static void pdc_error_intr (struct ata_port *ap,struct ata_queued_cmd *qc,u32 port_status,u32 err_mask) { -struct ata_eh_info *ehi = &ap->eh_info; +struct ata_eh_info *ehi = &ap->link.eh_info;unsigned int ac_err_mask =0 ;ata_ehi_clear_desc (ehi);
@@ -750,7 +750,7 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance) !(ap->flags & ATA_FLAG_DISABLED)) {struct ata_queued_cmd *qc; - qc =ata_qc_from_tag (ap, ap->active_tag); + qc =ata_qc_from_tag (ap, ap->link.active_tag);if (qc && (!(qc->tf.flags &ATA_TFLAG_POLLING ))) handled +=pdc_host_intr (ap, qc); }
drivers/ata/sata_qstor.c +2 -2
@@ -404,7 +404,7 @@ static inline unsigned int qs_intr_pkt(struct ata_host *host)struct qs_port_priv *pp = ap->private_data;if (!pp || pp->state != qs_state_pkt)continue ; - qc =ata_qc_from_tag (ap, ap->active_tag); + qc =ata_qc_from_tag (ap, ap->link.active_tag);if (qc && (!(qc->tf.flags &ATA_TFLAG_POLLING ))) {switch (sHST) {case 0 :/* successful CPB */
@@ -437,7 +437,7 @@ static inline unsigned int qs_intr_mmio(struct ata_host *host)struct qs_port_priv *pp = ap->private_data;if (!pp || pp->state != qs_state_mmio)continue ; - qc =ata_qc_from_tag (ap, ap->active_tag); + qc =ata_qc_from_tag (ap, ap->link.active_tag);if (qc && (!(qc->tf.flags &ATA_TFLAG_POLLING ))) {/* check main status, clearing INTRQ */
drivers/ata/sata_sil.c +7 -7
@@ -312,7 +312,7 @@ static int sil_set_mode (struct ata_port *ap, struct ata_device **r_failed)return rc;for (i =0 ; i <2 ; i++) { - dev = &ap->device[i]; + dev = &ap->link.device[i];if (!ata_dev_enabled (dev)) dev_mode[i] =0 ;/* PIO0/1/2 */ else if (dev->flags &ATA_DFLAG_PIO )
@@ -374,8 +374,8 @@ static int sil_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)static void sil_host_intr (struct ata_port *ap,u32 bmdma2) { -struct ata_eh_info *ehi = &ap->eh_info; -struct ata_queued_cmd *qc =ata_qc_from_tag (ap, ap->active_tag); +struct ata_eh_info *ehi = &ap->link.eh_info; +struct ata_queued_cmd *qc =ata_qc_from_tag (ap, ap->link.active_tag);u8 status;if (unlikely (bmdma2 &SIL_DMA_SATA_IRQ )) {
@@ -394,8 +394,8 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2)* repeat probing needlessly. */ if (!(ap->pflags &ATA_PFLAG_FROZEN )) { -ata_ehi_hotplugged (&ap->eh_info); - ap->eh_info.serror |= serror; +ata_ehi_hotplugged (&ap->link.eh_info); + ap->link.eh_info.serror |= serror; } goto freeze;
@@ -562,8 +562,8 @@ static void sil_thaw(struct ata_port *ap)*/ static void sil_dev_config (struct ata_device *dev) { -struct ata_port *ap = dev->ap; -int print_info = ap->eh_context.i.flags &ATA_EHI_PRINTINFO ; +struct ata_port *ap = dev->link->ap; +int print_info = ap->link.eh_context.i.flags &ATA_EHI_PRINTINFO ;unsigned int n, quirks =0 ;unsigned char model_num[ATA_ID_PROD_LEN +1 ];
drivers/ata/sata_sil24.c +6 -6
@@ -456,7 +456,7 @@ static int sil24_tag(int tag)static void sil24_dev_config (struct ata_device *dev) { -void __iomem *port = dev->ap->ioaddr.cmd_addr; +void __iomem *port = dev->link->ap->ioaddr.cmd_addr;if (dev->cdb_len ==16 )writel (PORT_CS_CDB16 , port +PORT_CTRL_STAT );
@@ -759,7 +759,7 @@ static void sil24_thaw(struct ata_port *ap)static void sil24_error_intr (struct ata_port *ap) {void __iomem *port = ap->ioaddr.cmd_addr; -struct ata_eh_info *ehi = &ap->eh_info; +struct ata_eh_info *ehi = &ap->link.eh_info;int freeze =0 ;u32 irq_stat;
@@ -811,7 +811,7 @@ static void sil24_error_intr(struct ata_port *ap) }/* record error info */ - qc =ata_qc_from_tag (ap, ap->active_tag); + qc =ata_qc_from_tag (ap, ap->link.active_tag);if (qc) {sil24_update_tf (ap); qc->err_mask |= err_mask;
@@ -855,7 +855,7 @@ static inline void sil24_host_intr(struct ata_port *ap)if (rc >0 )return ;if (rc <0 ) { -struct ata_eh_info *ehi = &ap->eh_info; +struct ata_eh_info *ehi = &ap->link.eh_info; ehi->err_mask |=AC_ERR_HSM ; ehi->action |=ATA_EH_SOFTRESET ;ata_port_freeze (ap);
@@ -865,7 +865,7 @@ static inline void sil24_host_intr(struct ata_port *ap)if (ata_ratelimit ())ata_port_printk (ap,KERN_INFO ,"spurious interrupt " "(slot_stat 0x%x active_tag %d sactive 0x%x)\n" , - slot_stat, ap->active_tag, ap->sactive); + slot_stat, ap->link.active_tag, ap->link.sactive); }static irqreturn_t sil24_interrupt (int irq,void *dev_instance)
@@ -907,7 +907,7 @@ static irqreturn_t sil24_interrupt(int irq, void *dev_instance)static void sil24_error_handler (struct ata_port *ap) { -struct ata_eh_context *ehc = &ap->eh_context; +struct ata_eh_context *ehc = &ap->link.eh_context;if (sil24_init_port (ap)) {ata_eh_freeze_port (ap);
drivers/ata/sata_sx4.c +2 -2
@@ -854,7 +854,7 @@ static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance) !(ap->flags & ATA_FLAG_DISABLED)) {struct ata_queued_cmd *qc; - qc =ata_qc_from_tag (ap, ap->active_tag); + qc =ata_qc_from_tag (ap, ap->link.active_tag);if (qc && (!(qc->tf.flags &ATA_TFLAG_POLLING ))) handled +=pdc20621_host_intr (ap, qc, (i >4 ), mmio_base);
@@ -881,7 +881,7 @@ static void pdc_eng_timeout(struct ata_port *ap)spin_lock_irqsave (&host->lock, flags); - qc =ata_qc_from_tag (ap, ap->active_tag); + qc =ata_qc_from_tag (ap, ap->link.active_tag);switch (qc->tf.protocol) {case ATA_PROT_DMA :
drivers/ata/sata_via.c +1 -1
@@ -296,7 +296,7 @@ static void svia_noop_freeze(struct ata_port *ap)*/ static int vt6420_prereset (struct ata_port *ap,unsigned long deadline) { -struct ata_eh_context *ehc = &ap->eh_context; +struct ata_eh_context *ehc = &ap->link.eh_context;unsigned long timeout = jiffies + (HZ *5 );u32 sstatus, scontrol;int online;
drivers/ata/sata_vsc.c +1 -1
@@ -240,7 +240,7 @@ static void vsc_port_intr(u8 port_status, struct ata_port *ap)return ; } - qc =ata_qc_from_tag (ap, ap->active_tag); + qc =ata_qc_from_tag (ap, ap->link.active_tag);if (qc &&likely (!(qc->tf.flags &ATA_TFLAG_POLLING ))) handled =ata_host_intr (ap, qc);
include/linux/libata.h +25 -15
@@ -432,7 +432,7 @@ struct ata_ering { };struct ata_device { -struct ata_port *ap; +struct ata_link *link;unsigned int devno;/* 0 or 1 */ unsigned long flags;/* ATA_DFLAG_xxx */ struct scsi_device *sdev;/* attached SCSI device */
@@ -506,6 +506,24 @@ struct ata_acpi_gtm {u32 flags; } __packed; +struct ata_link { +struct ata_port *ap; + +unsigned int active_tag;/* active tag on this link */ +u32 sactive;/* active NCQ commands */ + +unsigned int hw_sata_spd_limit; +unsigned int sata_spd_limit; +unsigned int sata_spd;/* current SATA PHY speed */ + +/* record runtime error info, protected by host_set lock */ +struct ata_eh_info eh_info; +/* EH context */ +struct ata_eh_context eh_context; + +struct ata_device device[ATA_MAX_DEVICES ]; +}; +struct ata_port {struct Scsi_Host *scsi_host;/* our co-allocated scsi host */ const struct ata_port_operations *ops;
@@ -529,23 +547,12 @@ struct ata_port {unsigned int mwdma_mask;unsigned int udma_mask;unsigned int cbl;/* cable type; ATA_CBL_xxx */ -unsigned int hw_sata_spd_limit; -unsigned int sata_spd_limit;/* SATA PHY speed limit */ -unsigned int sata_spd;/* current SATA PHY speed */ - -/* record runtime error info, protected by host lock */ -struct ata_eh_info eh_info; -/* EH context owned by EH */ -struct ata_eh_context eh_context; - -struct ata_device device[ATA_MAX_DEVICES ];struct ata_queued_cmd qcmd[ATA_MAX_QUEUE ];unsigned long qc_allocated;unsigned int qc_active; -unsigned int active_tag; -u32 sactive; +struct ata_link link;/* host default link */ struct ata_port_stats stats;struct ata_host *host;
@@ -907,8 +914,11 @@ extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset, #define ata_port_printk(ap, lv, fmt, args...) \ printk(lv"ata%u: "fmt, (ap)->print_id , ##args) +#define ata_link_printk(link, lv, fmt, args...) \ + printk(lv"ata%u: "fmt, (link)->ap->print_id , ##args) + #define ata_dev_printk(dev, lv, fmt, args...) \ - printk(lv"ata%u.%02u: "fmt, (dev)->ap->print_id, (dev)->devno , ##args) + printk(lv"ata%u.%02u: "fmt, (dev)->link->ap->print_id, (dev)->devno , ##args)/* * ata_eh_info helpers
@@ -1151,7 +1161,7 @@ static inline void ata_tf_init(struct ata_device *dev, struct ata_taskfile *tf) {memset (tf,0 ,sizeof (*tf)); - tf->ctl = dev->ap->ctl; + tf->ctl = dev->link->ap->ctl;if (dev->devno ==0 ) tf->device =ATA_DEVICE_OBS ;else
Signature · 1 line
1.5.0.3
PATCH 4/16 libata-link: implement and use link/device iterators
In reply to Tejun HeoMultiple links and different number of devices per link should be considered to iterate over links and devices. This patch implements and uses link and device iterators - ata_port_for_each_link() and ata_link_for_each_dev() - and ata_link_max_devices().
This change makes a lot of functions iterate over only possible devices instead of from dev 0 to dev ATA_MAX_DEVICES. All such changes have been examined and nothing should be broken.
While at it, add a separating comment before device helpers to distinguish them better from link helpers and others.
--- drivers/ata/ata_generic.c | 7 +-- drivers/ata/libata-acpi.c | 6 +- drivers/ata/libata-core.c | 58 +++++++++------------ drivers/ata/libata-eh.c | 117 +++++++++++++++++++++--------------------- drivers/ata/libata-scsi.c | 26 ++++------ drivers/ata/pata_it821x.c | 5 +- drivers/ata/pata_ixp4xx_cf.c | 5 +- drivers/ata/pata_legacy.c | 5 +- drivers/ata/pata_pdc2027x.c | 13 ++--- drivers/ata/pata_platform.c | 6 +-- drivers/ata/pata_rz1000.c | 5 +- drivers/ata/sata_sil.c | 12 ++--- include/linux/libata.h | 17 +++++- 13 files changed, 134 insertions(+), 148 deletions(-)
drivers/ata/ata_generic.c +3 -4
@@ -46,21 +46,20 @@static int generic_set_mode (struct ata_port *ap,struct ata_device **unused) {int dma_enabled =0 ; -int i; +struct ata_device *dev;/* Bits 5 and 6 indicate if DMA is active on master/slave */ if (ap->ioaddr.bmdma_addr) dma_enabled =ioread8 (ap->ioaddr.bmdma_addr +ATA_DMA_CMD ); -for (i =0 ; i <ATA_MAX_DEVICES ; i++) { -struct ata_device *dev = &ap->link.device[i]; +ata_link_for_each_dev (dev, &ap->link) {if (ata_dev_enabled (dev)) {/* We don't really care */ dev->pio_mode =XFER_PIO_0 ; dev->dma_mode =XFER_MW_DMA_0 ;/* We do need the right mode information for DMA or PIO and this comes from the current configuration flags */ -if (dma_enabled & (1 << (5 + i))) { +if (dma_enabled & (1 << (5 + dev->devno))) {ata_id_to_dma_mode (dev,XFER_MW_DMA_0 ); dev->flags &= ~ATA_DFLAG_PIO ; }else {
drivers/ata/libata-acpi.c +3 -3
@@ -509,7 +509,7 @@ int ata_acpi_on_suspend(struct ata_port *ap)*/ void ata_acpi_on_resume (struct ata_port *ap) { -int i; +struct ata_device *dev;if (ap->acpi_handle && (ap->pflags &ATA_PFLAG_GTM_VALID )) {BUG_ON (ap->flags &ATA_FLAG_ACPI_SATA );
@@ -519,8 +519,8 @@ void ata_acpi_on_resume(struct ata_port *ap) }/* schedule _GTF */ -for (i =0 ; i <ATA_MAX_DEVICES ; i++) - ap->link.device[i].flags |=ATA_DFLAG_ACPI_PENDING ; +ata_link_for_each_dev (dev, &ap->link) + dev->flags |=ATA_DFLAG_ACPI_PENDING ; }/**
drivers/ata/libata-core.c +24 -34
149 lines not on this page · raw message
drivers/ata/libata-eh.c +59 -58
275 lines not on this page · raw message
drivers/ata/libata-scsi.c +10 -16
@@ -2425,7 +2425,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)static struct ata_device *ata_find_dev (struct ata_port *ap,int id) { -if (likely (id <ATA_MAX_DEVICES )) +if (likely (id <ata_link_max_devices (&ap->link)))return &ap->link.device[id];return NULL ; }
@@ -2952,21 +2952,18 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync)int tries =5 ;struct ata_device *last_failed_dev =NULL ;struct ata_device *dev; -unsigned int i;if (ap->flags &ATA_FLAG_DISABLED )return ; repeat: -for (i =0 ; i <ATA_MAX_DEVICES ; i++) { +ata_link_for_each_dev (dev, &ap->link) {struct scsi_device *sdev; - dev = &ap->link.device[i]; -if (!ata_dev_enabled (dev) || dev->sdev)continue ; - sdev =__scsi_add_device (ap->scsi_host,0 , i,0 ,NULL ); + sdev =__scsi_add_device (ap->scsi_host,0 , dev->devno,0 ,NULL );if (!IS_ERR (sdev)) { dev->sdev = sdev;scsi_device_put (sdev);
@@ -2977,12 +2974,11 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync)* failure occurred, scan would have failed silently. Check * whether all devices are attached. */ -for (i =0 ; i <ATA_MAX_DEVICES ; i++) { - dev = &ap->link.device[i]; +ata_link_for_each_dev (dev, &ap->link) {if (ata_dev_enabled (dev) && !dev->sdev)break ; } -if (i ==ATA_MAX_DEVICES ) +if (!dev)return ;/* we're missing some SCSI devices */
@@ -3112,7 +3108,7 @@ void ata_scsi_hotplug(struct work_struct *work) {struct ata_port *ap = container_of(work, struct ata_port, hotplug_task.work); -int i; +struct ata_device *dev;if (ap->pflags &ATA_PFLAG_UNLOADING ) {DPRINTK ("ENTER/EXIT - unloading\n" );
@@ -3122,8 +3118,7 @@ void ata_scsi_hotplug(struct work_struct *work)DPRINTK ("ENTER\n" );/* unplug detached devices */ -for (i =0 ; i <ATA_MAX_DEVICES ; i++) { -struct ata_device *dev = &ap->link.device[i]; +ata_link_for_each_dev (dev, &ap->link) {unsigned long flags;if (!(dev->flags &ATA_DFLAG_DETACHED ))
@@ -3176,7 +3171,7 @@ static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,spin_lock_irqsave (ap->lock, flags);if (id ==SCAN_WILD_CARD ) { - ehi->probe_mask |= (1 <<ATA_MAX_DEVICES ) -1 ; + ehi->probe_mask |= (1 <<ata_link_max_devices (&ap->link)) -1 ; ehi->action |=ATA_EH_SOFTRESET ; }else {struct ata_device *dev =ata_find_dev (ap, id);
@@ -3215,13 +3210,12 @@ void ata_scsi_dev_rescan(struct work_struct *work) {struct ata_port *ap = container_of(work, struct ata_port, scsi_rescan_task); +struct ata_device *dev;unsigned long flags; -unsigned int i;spin_lock_irqsave (ap->lock, flags); -for (i =0 ; i <ATA_MAX_DEVICES ; i++) { -struct ata_device *dev = &ap->link.device[i]; +ata_link_for_each_dev (dev, &ap->link) {struct scsi_device *sdev = dev->sdev;if (!ata_dev_enabled (dev) || !sdev)
drivers/ata/pata_it821x.c +2 -3
@@ -461,10 +461,9 @@ static unsigned int it821x_passthru_qc_issue_prot(struct ata_queued_cmd *qc)static int it821x_smart_set_mode (struct ata_port *ap,struct ata_device **unused) { -int i; +struct ata_device *dev; -for (i =0 ; i <ATA_MAX_DEVICES ; i++) { -struct ata_device *dev = &ap->link.device[i]; +ata_link_for_each_dev (dev, &ap->link) {if (ata_dev_enabled (dev)) {/* We don't really care */ dev->pio_mode =XFER_PIO_0 ;
drivers/ata/pata_ixp4xx_cf.c +2 -3
@@ -28,10 +28,9 @@static int ixp4xx_set_mode (struct ata_port *ap,struct ata_device **error) { -int i; +struct ata_device *dev; -for (i =0 ; i <ATA_MAX_DEVICES ; i++) { -struct ata_device *dev = &ap->link.device[i]; +ata_link_for_each_dev (dev, &ap->link) {if (ata_dev_enabled (dev)) {ata_dev_printk (dev,KERN_INFO ,"configured for PIO0\n" ); dev->pio_mode =XFER_PIO_0 ;
drivers/ata/pata_legacy.c +2 -3
@@ -109,10 +109,9 @@ static int iordy_mask = 0xFFFFFFFF; /* Use iordy if available */static int legacy_set_mode (struct ata_port *ap,struct ata_device **unused) { -int i; +struct ata_device *dev; -for (i =0 ; i <ATA_MAX_DEVICES ; i++) { -struct ata_device *dev = &ap->link.device[i]; +ata_link_for_each_dev (dev, &ap->link) {if (ata_dev_enabled (dev)) {ata_dev_printk (dev,KERN_INFO ,"configured for PIO\n" ); dev->pio_mode =XFER_PIO_0 ;
drivers/ata/pata_pdc2027x.c +6 -7
@@ -479,15 +479,14 @@ static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev)*/ static int pdc2027x_set_mode (struct ata_port *ap,struct ata_device **r_failed) { -int i; - - i =ata_do_set_mode (ap, r_failed); -if (i <0 ) -return i; +struct ata_device *dev; +int rc; -for (i =0 ; i <ATA_MAX_DEVICES ; i++) { -struct ata_device *dev = &ap->link.device[i]; + rc =ata_do_set_mode (ap, r_failed); +if (rc <0 ) +return rc; +ata_link_for_each_dev (dev, &ap->link) {if (ata_dev_enabled (dev)) {pdc2027x_set_piomode (ap, dev);
drivers/ata/pata_platform.c +2 -4
@@ -32,11 +32,9 @@ static int pio_mask = 1;*/ static int pata_platform_set_mode (struct ata_port *ap,struct ata_device **unused) { -int i; - -for (i =0 ; i <ATA_MAX_DEVICES ; i++) { -struct ata_device *dev = &ap->link.device[i]; +struct ata_device *dev; +ata_link_for_each_dev (dev, &ap->link) {if (ata_dev_enabled (dev)) {/* We don't really care */ dev->pio_mode = dev->xfer_mode =XFER_PIO_0 ;
drivers/ata/pata_rz1000.c +2 -3
@@ -36,10 +36,9 @@static int rz1000_set_mode (struct ata_port *ap,struct ata_device **unused) { -int i; +struct ata_device *dev; -for (i =0 ; i <ATA_MAX_DEVICES ; i++) { -struct ata_device *dev = &ap->link.device[i]; +ata_link_for_each_dev (dev, &ap->link) {if (ata_dev_enabled (dev)) {/* We don't really care */ dev->pio_mode =XFER_PIO_0 ;
drivers/ata/sata_sil.c +5 -7
@@ -303,22 +303,20 @@ static int sil_set_mode (struct ata_port *ap, struct ata_device **r_failed)struct ata_device *dev;void __iomem *mmio_base = host->iomap[SIL_MMIO_BAR ];void __iomem *addr = mmio_base + sil_port[ap->port_no].xfer_mode; -u32 tmp, dev_mode[2 ]; -unsigned int i; +u32 tmp, dev_mode[2 ] = { };int rc; rc =ata_do_set_mode (ap, r_failed);if (rc)return rc; -for (i =0 ; i <2 ; i++) { - dev = &ap->link.device[i]; +ata_link_for_each_dev (dev, &ap->link) {if (!ata_dev_enabled (dev)) - dev_mode[i] =0 ;/* PIO0/1/2 */ + dev_mode[dev->devno] =0 ;/* PIO0/1/2 */ else if (dev->flags &ATA_DFLAG_PIO ) - dev_mode[i] =1 ;/* PIO3/4 */ + dev_mode[dev->devno] =1 ;/* PIO3/4 */ else - dev_mode[i] =3 ;/* UDMA */ + dev_mode[dev->devno] =3 ;/* UDMA */ /* value 2 indicates MDMA */ }
include/linux/libata.h +14 -3
@@ -1032,15 +1032,26 @@ static inline unsigned int ata_dev_absent(const struct ata_device *dev) }/* -* port helpers +* link helpers */ -static inline int ata_port_max_devices (const struct ata_port *ap) +static inline int ata_link_max_devices (const struct ata_link *link) { -if (ap->flags &ATA_FLAG_SLAVE_POSS ) +if (link->ap->flags &ATA_FLAG_SLAVE_POSS )return 2 ;return 1 ; } +#define ata_port_for_each_link (lk, ap) \ + for ((lk) = &(ap)->link; (lk); (lk) = NULL) + +#define ata_link_for_each_dev (dev, link) \ + for ((dev) = (link)->device; \ + (dev) < (link)->device + ata_link_max_devices(link) || ((dev) = NULL); \ + (dev)++) + +#define ata_link_for_each_dev_reverse (dev, link) \ + for ((dev) = (link)->device + ata_link_max_devices(link) - 1; \ + (dev) >= (link)->device || ((dev) = NULL); (dev)--)static inline u8 ata_chk_status (struct ata_port *ap) {
Signature · 1 line
1.5.0.3
PATCH 5/16 libata-link: linkify PHY-related functions
In reply to Tejun HeoMake the following PHY-related functions to deal with ata_link instead of ata_port.
* sata_print_link_status()
* sata_down_spd_limit()
* ata_set_sata_spd_limit() and friends
* sata_link_debounce/resume()
* sata_scr_valid/read/write/write_flush()
* ata_link_on/offline()
This patch introduces no behavior change.
--- drivers/ata/ahci.c | 4 +- drivers/ata/libata-core.c | 227 +++++++++++++++++++++++-------------------- drivers/ata/libata-eh.c | 31 +++--- drivers/ata/libata-sff.c | 2 +- drivers/ata/libata.h | 4 +- drivers/ata/pata_scc.c | 2 +- drivers/ata/sata_inic162x.c | 4 +- drivers/ata/sata_mv.c | 14 ++-- drivers/ata/sata_promise.c | 4 +- drivers/ata/sata_sil24.c | 10 +- include/linux/libata.h | 24 +++--- 11 files changed, 171 insertions(+), 155 deletions(-)
drivers/ata/ahci.c +2 -2
@@ -952,7 +952,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class,DPRINTK ("ENTER\n" ); -if (ata_port_offline (ap)) { +if (ata_link_offline (&ap->link)) {DPRINTK ("PHY reports no device\n" ); *class =ATA_DEV_NONE ;return 0 ;
@@ -1063,7 +1063,7 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class,ahci_start_engine (ap); -if (rc ==0 &&ata_port_online (ap)) +if (rc ==0 &&ata_link_online (&ap->link)) *class =ahci_dev_classify (ap);if (*class ==ATA_DEV_UNKNOWN ) *class =ATA_DEV_NONE ;
drivers/ata/libata-core.c +121 -106
628 lines not on this page · raw message
drivers/ata/libata-eh.c +16 -15
@@ -1436,7 +1436,7 @@ static unsigned int ata_eh_speed_down(struct ata_device *dev, int is_io,/* speed down? */ if (verdict &ATA_EH_SPDN_SPEED_DOWN ) {/* speed down SATA link speed if possible */ -if (sata_down_spd_limit (dev->link->ap) ==0 ) { +if (sata_down_spd_limit (dev->link) ==0 ) { action |=ATA_EH_HARDRESET ; goto done; }
@@ -1496,7 +1496,8 @@ static unsigned int ata_eh_speed_down(struct ata_device *dev, int is_io,*/ static void ata_eh_autopsy (struct ata_port *ap) { -struct ata_eh_context *ehc = &ap->link.eh_context; +struct ata_link *link = &ap->link; +struct ata_eh_context *ehc = &link->eh_context;unsigned int all_err_mask =0 ;int tag, is_io =0 ;u32 serror;
@@ -1508,7 +1509,7 @@ static void ata_eh_autopsy(struct ata_port *ap)return ;/* obtain and analyze SError */ - rc =sata_scr_read (ap,SCR_ERROR , &serror); + rc =sata_scr_read (link,SCR_ERROR , &serror);if (rc ==0 ) { ehc->i.serror |= serror;ata_eh_analyze_serror (ap);
@@ -1717,7 +1718,8 @@ static int ata_eh_reset(struct ata_port *ap, 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 = &ap->link.eh_context; + struct ata_link *link = &ap->link; +struct ata_eh_context *ehc = &link->eh_context;unsigned int *classes = ehc->classes;int verbose = !(ehc->i.flags &ATA_EHI_QUIET );int try =0 ;
@@ -1735,7 +1737,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify,*/ action = ehc->i.action; ehc->i.action &= ~ATA_EH_RESET_MASK ; -if (softreset && (!hardreset || (!sata_set_spd_needed (ap) && +if (softreset && (!hardreset || (!sata_set_spd_needed (link) && !(action &ATA_EH_HARDRESET )))) ehc->i.action |=ATA_EH_SOFTRESET ;else
@@ -1749,7 +1751,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, "port disabled. ignoring.\n"); ehc->i.action &= ~ATA_EH_RESET_MASK ; -ata_link_for_each_dev (dev, &ap->link) +ata_link_for_each_dev (dev, link) classes[dev->devno] =ATA_DEV_NONE ; rc =0 ;
@@ -1767,7 +1769,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, reset = softreset; else {/* prereset told us not to reset, bang classes and return */ -ata_link_for_each_dev (dev, &ap->link) +ata_link_for_each_dev (dev, link) classes[dev->devno] =ATA_DEV_NONE ; rc =0 ; goto out;
@@ -1837,7 +1839,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify,if (rc == -EPIPE || try ==ARRAY_SIZE (ata_eh_reset_timeouts) -1 ) -sata_down_spd_limit (ap); +sata_down_spd_limit (link);if (hardreset) reset = hardreset; goto retry;
@@ -1849,12 +1851,12 @@ static int ata_eh_reset(struct ata_port *ap, int classify,/* After the reset, the device state is PIO 0 and the * controller state is undefined. Record the mode. */ -ata_link_for_each_dev (dev, &ap->link) +ata_link_for_each_dev (dev, link) dev->pio_mode =XFER_PIO_0 ;/* record current link speed */ -if (sata_scr_read (ap,SCR_STATUS , &sstatus) ==0 ) - ap->link.sata_spd = (sstatus >>4 ) &0xf ; +if (sata_scr_read (link,SCR_STATUS , &sstatus) ==0 ) + link->sata_spd = (sstatus >>4 ) &0xf ;if (postreset)postreset (ap, classes);
@@ -1892,7 +1894,7 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap, readid_flags |=ATA_READID_POSTRESET ;if ((action &ATA_EH_REVALIDATE ) &&ata_dev_enabled (dev)) { -if (ata_port_offline (ap)) { +if (ata_link_offline (&ap->link)) { rc = -EIO ; goto err; }
@@ -2014,7 +2016,6 @@ static int ata_eh_skip_recovery(struct ata_port *ap)static void ata_eh_handle_dev_fail (struct ata_device *dev,int err) { -struct ata_port *ap = dev->link->ap;struct ata_eh_context *ehc = &dev->link->eh_context; ehc->tries[dev->devno]--;
@@ -2031,7 +2032,7 @@ static void ata_eh_handle_dev_fail(struct ata_device *dev, int err)/* This is the last chance, better to slow * down than lose it. */ -sata_down_spd_limit (ap); +sata_down_spd_limit (dev->link);ata_down_xfermask_limit (dev,ATA_DNXFER_PIO ); } }
@@ -2041,7 +2042,7 @@ static void ata_eh_handle_dev_fail(struct ata_device *dev, int err)ata_dev_disable (dev);/* detach if offline */ -if (ata_port_offline (ap)) +if (ata_link_offline (dev->link))ata_eh_detach_dev (dev);/* probe if requested */
drivers/ata/libata-sff.c +1 -1
@@ -495,7 +495,7 @@ void ata_bmdma_error_handler(struct ata_port *ap)ata_reset_fn_t hardreset; hardreset =NULL ; -if (sata_scr_valid (ap)) +if (sata_scr_valid (&ap->link)) hardreset = sata_std_hardreset; ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, hardreset,
drivers/ata/libata.h +2 -2
@@ -78,8 +78,8 @@ extern int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,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_configure (struct ata_device *dev); -extern int sata_down_spd_limit (struct ata_port *ap); -extern int sata_set_spd_needed (struct ata_port *ap); +extern int sata_down_spd_limit (struct ata_link *link); +extern int sata_set_spd_needed (struct ata_link *link);extern int ata_down_xfermask_limit (struct ata_device *dev,unsigned int sel);extern int ata_set_mode (struct ata_port *ap,struct ata_device **r_failed_dev);extern void ata_sg_clean (struct ata_queued_cmd *qc);
drivers/ata/pata_scc.c +1 -1
@@ -599,7 +599,7 @@ static int scc_std_softreset (struct ata_port *ap, unsigned int *classes,DPRINTK ("ENTER\n" ); -if (ata_port_offline (ap)) { +if (ata_link_offline (&ap->link)) { classes[0 ] =ATA_DEV_NONE ; goto out; }
drivers/ata/sata_inic162x.c +2 -2
@@ -435,7 +435,7 @@ static int inic_hardreset(struct ata_port *ap, unsigned int *class,msleep (1 );writew (val & ~IDMA_CTL_RST_ATA , idma_ctl); - rc =sata_phy_resume (ap, timing, deadline); + rc =sata_link_resume (&ap->link, timing, deadline);if (rc) {ata_port_printk (ap,KERN_WARNING ,"failed to resume " "link after reset (errno=%d)\n" , rc);
@@ -443,7 +443,7 @@ static int inic_hardreset(struct ata_port *ap, unsigned int *class, } *class =ATA_DEV_NONE ; -if (ata_port_online (ap)) { +if (ata_link_online (&ap->link)) {struct ata_taskfile tf;/* wait a while before checking status */
drivers/ata/sata_mv.c +7 -7
@@ -1340,8 +1340,8 @@ static void mv_err_intr(struct ata_port *ap, int reset_allowed) edma_err_cause =readl (port_mmio +EDMA_ERR_IRQ_CAUSE_OFS );if (EDMA_ERR_SERR & edma_err_cause) { -sata_scr_read (ap,SCR_ERROR , &serr); -sata_scr_write_flush (ap,SCR_ERROR , serr); +sata_scr_read (&ap->link,SCR_ERROR , &serr); +sata_scr_write_flush (&ap->link,SCR_ERROR , serr); }if (EDMA_ERR_SELF_DIS & edma_err_cause) {struct mv_port_priv *pp = ap->private_data;
@@ -1990,15 +1990,15 @@ static void __mv_phy_reset(struct ata_port *ap, int can_sleep)/* Issue COMRESET via SControl */ comreset_retry: -sata_scr_write_flush (ap,SCR_CONTROL ,0x301 ); +sata_scr_write_flush (&ap->link,SCR_CONTROL ,0x301 );__msleep (1 , can_sleep); -sata_scr_write_flush (ap,SCR_CONTROL ,0x300 ); +sata_scr_write_flush (&ap->link,SCR_CONTROL ,0x300 );__msleep (20 , can_sleep); timeout = jiffies +msecs_to_jiffies (200 ); do { - sata_scr_read(ap, SCR_STATUS, &sstatus); + sata_scr_read(&ap->link, SCR_STATUS, &sstatus); if (((sstatus & 0x3) == 3) || ((sstatus & 0x3) == 0)) break;
@@ -2023,10 +2023,10 @@ comreset_retry: }#endif -if (ata_port_online (ap)) { +if (ata_link_online (&ap->link)) {ata_port_probe (ap); }else { -sata_scr_read (ap,SCR_STATUS , &sstatus); +sata_scr_read (&ap->link,SCR_STATUS , &sstatus);ata_port_printk (ap,KERN_INFO ,"no device found (phy stat %08x)\n" , sstatus);ata_port_disable (ap);
drivers/ata/sata_promise.c +2 -2
@@ -480,7 +480,7 @@ static void pdc_atapi_pkt(struct ata_queued_cmd *qc) buf32[2 ] =0 ;/* no next-packet */ /* select drive */ -if (sata_scr_valid (ap)) { +if (sata_scr_valid (&ap->link)) { dev_sel =PDC_DEVICE_SATA ; }else { dev_sel =ATA_DEVICE_OBS ;
@@ -648,7 +648,7 @@ static void pdc_error_intr(struct ata_port *ap, struct ata_queued_cmd *qc, | PDC_PCI_SYS_ERR | PDC1_PCI_PARITY_ERR)) ac_err_mask |=AC_ERR_HOST_BUS ; -if (sata_scr_valid (ap)) { +if (sata_scr_valid (&ap->link)) {u32 serror;pdc_sata_scr_read (ap,SCR_ERROR , &serror);
drivers/ata/sata_sil24.c +5 -5
@@ -548,7 +548,7 @@ static int sil24_softreset(struct ata_port *ap, unsigned int *class,DPRINTK ("ENTER\n" ); -if (ata_port_offline (ap)) { +if (ata_link_offline (&ap->link)) {DPRINTK ("PHY reports no device\n" ); *class =ATA_DEV_NONE ; goto out;
@@ -606,10 +606,10 @@ static int sil24_hardreset(struct ata_port *ap, unsigned int *class,u32 tmp;/* sil24 does the right thing(tm) without any protection */ -sata_set_spd (ap); +sata_set_spd (&ap->link); tout_msec =100 ; -if (ata_port_online (ap)) +if (ata_link_online (&ap->link)) tout_msec =5000 ;writel (PORT_CS_DEV_RST , port +PORT_CTRL_STAT );
@@ -619,14 +619,14 @@ static int sil24_hardreset(struct ata_port *ap, unsigned int *class,/* SStatus oscillates between zero and valid status after * DEV_RST, debounce it. */ - rc =sata_phy_debounce (ap, sata_deb_timing_long, deadline); + rc =sata_link_debounce (&ap->link, sata_deb_timing_long, deadline);if (rc) { reason ="PHY debouncing failed" ; goto err; }if (tmp &PORT_CS_DEV_RST ) { -if (ata_port_offline (ap)) +if (ata_link_offline (&ap->link))return 0 ; reason ="link not ready" ; goto err;
include/linux/libata.h +12 -12
@@ -692,16 +692,16 @@ static inline int ata_port_is_dummy(struct ata_port *ap)return ap->ops == &ata_dummy_port_ops; } -extern void sata_print_link_status (struct ata_port *ap); +extern void sata_print_link_status (struct ata_link *link);extern void ata_port_probe (struct ata_port *);extern void __sata_phy_reset (struct ata_port *ap);extern void sata_phy_reset (struct ata_port *ap);extern void ata_bus_reset (struct ata_port *ap); -extern int sata_set_spd (struct ata_port *ap); -extern int sata_phy_debounce (struct ata_port *ap,const unsigned long *param, -unsigned long deadline); -extern int sata_phy_resume (struct ata_port *ap,const unsigned long *param, -unsigned long deadline); +extern int sata_set_spd (struct ata_link *link); +extern int sata_link_debounce (struct ata_link *link, +const unsigned long *params,unsigned long deadline); +extern int sata_link_resume (struct ata_link *link,const unsigned long *params, +unsigned long deadline);extern int ata_std_prereset (struct ata_port *ap,unsigned long deadline);extern int ata_std_softreset (struct ata_port *ap,unsigned int *classes,unsigned long deadline);
@@ -749,12 +749,12 @@ extern int ata_sas_slave_configure(struct scsi_device *, struct ata_port *);extern int ata_sas_queuecmd (struct scsi_cmnd *cmd,void (*done)(struct scsi_cmnd *),struct ata_port *ap);extern unsigned int ata_host_intr (struct ata_port *ap,struct ata_queued_cmd *qc); -extern int sata_scr_valid (struct ata_port *ap); -extern int sata_scr_read (struct ata_port *ap,int reg,u32 *val); -extern int sata_scr_write (struct ata_port *ap,int reg,u32 val); -extern int sata_scr_write_flush (struct ata_port *ap,int reg,u32 val); -extern int ata_port_online (struct ata_port *ap); -extern int ata_port_offline (struct ata_port *ap); +extern int sata_scr_valid (struct ata_link *link); +extern int sata_scr_read (struct ata_link *link,int reg,u32 *val); +extern int sata_scr_write (struct ata_link *link,int reg,u32 val); +extern int sata_scr_write_flush (struct ata_link *link,int reg,u32 val); +extern int ata_link_online (struct ata_link *link); +extern int ata_link_offline (struct ata_link *link);#ifdef CONFIG_PM extern int ata_host_suspend (struct ata_host *host,pm_message_t mesg);extern void ata_host_resume (struct ata_host *host);
Signature · 1 line
1.5.0.3
PATCH 6/16 libata-link: linkify EH action helpers
In reply to Tejun HeoMake ata_eh_about_to_do() and ata_eh_done() deal with ata_link instead of ata_port.
This patch introduces no behavior change.
--- drivers/ata/libata-eh.c | 35 ++++++++++++++++++----------------- 1 files changed, 18 insertions(+), 17 deletions(-)
drivers/ata/libata-eh.c +18 -17
@@ -882,23 +882,24 @@ static void ata_eh_detach_dev(struct ata_device *dev)/** * ata_eh_about_to_do - about to perform eh_action -* @ap: target ATA port +* @link: target ATA link * @dev: target ATA dev for per-dev action (can be NULL) * @action: action about to be performed * * Called just before performing EH actions to clear related bits -* in @ap->link.eh_info such that eh actions are not -* unnecessarily repeated. +* in @link->eh_info such that eh actions are not unnecessarily +* repeated. * * LOCKING: * None. */ -static void ata_eh_about_to_do (struct ata_port *ap,struct ata_device *dev, +static 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; +struct ata_eh_context *ehc = &link->eh_context;unsigned long flags; -struct ata_eh_info *ehi = &ap->link.eh_info; -struct ata_eh_context *ehc = &ap->link.eh_context;spin_lock_irqsave (ap->lock, flags);
@@ -915,7 +916,7 @@ static void ata_eh_about_to_do(struct ata_port *ap, struct ata_device *dev, ehi->flags &= ~ATA_EHI_RESET_MODIFIER_MASK ; } -ata_eh_clear_action (&ap->link, dev, ehi, action); +ata_eh_clear_action (link, dev, ehi, action);if (!(ehc->i.flags &ATA_EHI_QUIET )) ap->pflags |=ATA_PFLAG_RECOVERED ;
@@ -925,20 +926,20 @@ static void ata_eh_about_to_do(struct ata_port *ap, struct ata_device *dev,/** * ata_eh_done - EH action complete -* @ap: target ATA port +* @ap: target ATA port * @dev: target ATA dev for per-dev action (can be NULL) * @action: action just completed * * Called right after performing EH actions to clear related bits -* in @ap->link.eh_context. +* in @link->eh_context. * * LOCKING: * None. */ -static void ata_eh_done (struct ata_port *ap,struct ata_device *dev, +static void ata_eh_done (struct ata_link *link,struct ata_device *dev,unsigned int action) { -struct ata_eh_context *ehc = &ap->link.eh_context; +struct ata_eh_context *ehc = &link->eh_context;/* if reset is complete, clear all reset actions & reset modifier */ if (action &ATA_EH_RESET_MASK ) {
@@ -946,7 +947,7 @@ static void ata_eh_done(struct ata_port *ap, struct ata_device *dev, ehc->i.flags &= ~ATA_EHI_RESET_MODIFIER_MASK ; } -ata_eh_clear_action (&ap->link, dev, &ehc->i, action); +ata_eh_clear_action (link, dev, &ehc->i, action); }/**
@@ -1730,7 +1731,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify,int rc;/* about to reset */ -ata_eh_about_to_do (ap,NULL , ehc->i.action &ATA_EH_RESET_MASK ); +ata_eh_about_to_do (link,NULL , ehc->i.action &ATA_EH_RESET_MASK );/* Determine which reset to use and record in ehc->i.action. * prereset() may examine and modify it.
@@ -1812,7 +1813,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, goto out; } -ata_eh_about_to_do (ap,NULL ,ATA_EH_RESET_MASK ); +ata_eh_about_to_do (link,NULL ,ATA_EH_RESET_MASK ); rc =ata_do_reset (ap, reset, classes, deadline); if (rc == 0 && classify &&
@@ -1862,7 +1863,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify,postreset (ap, classes);/* reset successful, schedule revalidation */ -ata_eh_done (ap,NULL , ehc->i.action &ATA_EH_RESET_MASK ); +ata_eh_done (link,NULL , ehc->i.action &ATA_EH_RESET_MASK ); ehc->i.action |=ATA_EH_REVALIDATE ; } out:
@@ -1899,12 +1900,12 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap, goto err; } -ata_eh_about_to_do (ap, dev,ATA_EH_REVALIDATE ); +ata_eh_about_to_do (&ap->link, dev,ATA_EH_REVALIDATE ); rc =ata_dev_revalidate (dev, readid_flags);if (rc) goto err; -ata_eh_done (ap, dev,ATA_EH_REVALIDATE ); +ata_eh_done (&ap->link, dev,ATA_EH_REVALIDATE );/* Configuration may have changed, reconfigure * transfer mode.
Signature · 1 line
1.5.0.3
PATCH 7/16 libata-link: linkify reset
In reply to Tejun HeoMake reset methods and related functions deal with ata_link instead of ata_port.
* ata_do_reset()
* ata_eh_reset()
* all prereset/reset/postreset methods and related functions
This patch introduces no behavior change.
--- drivers/ata/ahci.c | 28 ++++++++++++++---------- drivers/ata/ata_piix.c | 7 +++-- drivers/ata/libata-core.c | 49 +++++++++++++++++++++---------------------- drivers/ata/libata-eh.c | 35 +++++++++++++++--------------- drivers/ata/pata_amd.c | 16 ++++++++------ drivers/ata/pata_artop.c | 12 ++++++---- drivers/ata/pata_atiixp.c | 5 ++- drivers/ata/pata_efar.c | 7 +++-- drivers/ata/pata_hpt37x.c | 12 ++++++---- drivers/ata/pata_hpt3x2n.c | 7 +++-- drivers/ata/pata_it8213.c | 7 +++-- drivers/ata/pata_jmicron.c | 8 +++--- drivers/ata/pata_marvell.c | 7 +++-- drivers/ata/pata_mpiix.c | 5 ++- drivers/ata/pata_ns87410.c | 7 +++-- drivers/ata/pata_oldpiix.c | 7 +++-- drivers/ata/pata_opti.c | 7 +++-- drivers/ata/pata_optidma.c | 7 +++-- drivers/ata/pata_pdc2027x.c | 8 +++--- drivers/ata/pata_sil680.c | 7 +++-- drivers/ata/pata_sis.c | 7 +++-- drivers/ata/pata_sl82c105.c | 7 +++-- drivers/ata/pata_triflex.c | 7 +++-- drivers/ata/pata_via.c | 5 ++- drivers/ata/sata_inic162x.c | 13 ++++++----- drivers/ata/sata_nv.c | 4 +- drivers/ata/sata_sil24.c | 20 +++++++++-------- drivers/ata/sata_via.c | 5 ++- include/linux/libata.h | 19 ++++++++-------- 29 files changed, 182 insertions(+), 153 deletions(-)
drivers/ata/ahci.c +16 -12
@@ -938,9 +938,10 @@ static int ahci_clo(struct ata_port *ap)return 0 ; } -static int ahci_softreset (struct ata_port *ap,unsigned int *class, +static int ahci_softreset (struct ata_link *link,unsigned int *class,unsigned long deadline) { +struct ata_port *ap = link->ap;struct ahci_port_priv *pp = ap->private_data;void __iomem *port_mmio =ahci_port_base (ap);const u32 cmd_fis_len =5 ;/* five dwords */
@@ -952,7 +953,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class,DPRINTK ("ENTER\n" ); -if (ata_link_offline (&ap->link)) { +if (ata_link_offline (link)) {DPRINTK ("PHY reports no device\n" ); *class =ATA_DEV_NONE ;return 0 ;
@@ -981,7 +982,7 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class,/* restart engine */ ahci_start_engine (ap); -ata_tf_init (ap->link.device, &tf); +ata_tf_init (link->device, &tf); fis = pp->cmd_tbl;/* issue the first D2H Register FIS */
@@ -1038,13 +1039,14 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class, fail_restart:ahci_start_engine (ap); fail: -ata_port_printk (ap,KERN_ERR ,"softreset failed (%s)\n" , reason); +ata_link_printk (link,KERN_ERR ,"softreset failed (%s)\n" , reason);return rc; } -static int ahci_hardreset (struct ata_port *ap,unsigned int *class, +static int ahci_hardreset (struct ata_link *link,unsigned int *class,unsigned long deadline) { +struct ata_port *ap = link->ap;struct ahci_port_priv *pp = ap->private_data;u8 *d2h_fis = pp->rx_fis +RX_FIS_D2H_REG ;struct ata_taskfile tf;
@@ -1055,15 +1057,15 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class,ahci_stop_engine (ap);/* clear D2H reception area to properly wait for D2H FIS */ -ata_tf_init (ap->link.device, &tf); +ata_tf_init (link->device, &tf); tf.command =0x80 ;ata_tf_to_fis (&tf, d2h_fis,0 ); - rc =sata_std_hardreset (ap, class, deadline); + rc =sata_std_hardreset (link, class, deadline);ahci_start_engine (ap); -if (rc ==0 &&ata_link_online (&ap->link)) +if (rc ==0 &&ata_link_online (link)) *class =ahci_dev_classify (ap);if (*class ==ATA_DEV_UNKNOWN ) *class =ATA_DEV_NONE ;
@@ -1072,9 +1074,10 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class,return rc; } -static int ahci_vt8251_hardreset (struct ata_port *ap,unsigned int *class, +static int ahci_vt8251_hardreset (struct ata_link *link,unsigned int *class,unsigned long deadline) { +struct ata_port *ap = link->ap;u32 serror;int rc;
@@ -1082,7 +1085,7 @@ static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class,ahci_stop_engine (ap); - rc =sata_port_hardreset (ap,sata_ehc_deb_timing (&ap->link.eh_context), + rc =sata_link_hardreset (link,sata_ehc_deb_timing (&link->eh_context), deadline);/* vt8251 needs SError cleared for the port to operate */
@@ -1099,12 +1102,13 @@ static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class,return rc ?: -EAGAIN ; } -static void ahci_postreset (struct ata_port *ap,unsigned int *class) +static void ahci_postreset (struct ata_link *link,unsigned int *class) { +struct ata_port *ap = link->ap;void __iomem *port_mmio =ahci_port_base (ap);u32 new_tmp, tmp; -ata_std_postreset (ap, class); +ata_std_postreset (link, class);/* Make sure port's ATAPI bit is set appropriately */ new_tmp = tmp =readl (port_mmio +PORT_CMD );
drivers/ata/ata_piix.c +4 -3
@@ -620,19 +620,20 @@ static int ich_pata_cable_detect(struct ata_port *ap)/** * piix_pata_prereset - prereset for PATA host controller -* @ap: Target port +* @link: Target link * @deadline: deadline jiffies for the operation * * LOCKING: * None (inherited from caller). */ -static int piix_pata_prereset (struct ata_port *ap,unsigned long deadline) +static int piix_pata_prereset (struct ata_link *link,unsigned long deadline) { +struct ata_port *ap = link->ap;struct pci_dev *pdev =to_pci_dev (ap->host->dev);if (!pci_test_config_bits (pdev, &piix_enable_bits[ap->port_no]))return -ENOENT ; -return ata_std_prereset (ap, deadline); +return ata_std_prereset (link, deadline); }static void piix_pata_error_handler (struct ata_port *ap)
drivers/ata/libata-core.c +24 -25
159 lines not on this page · raw message
drivers/ata/libata-eh.c +17 -18
@@ -1672,16 +1672,16 @@ static void ata_eh_report(struct ata_port *ap) } } -static int ata_do_reset (struct ata_port *ap,ata_reset_fn_t reset, +static int ata_do_reset (struct ata_link *link,ata_reset_fn_t reset,unsigned int *classes,unsigned long deadline) {struct ata_device *dev;int rc; -ata_link_for_each_dev (dev, &ap->link) +ata_link_for_each_dev (dev, link) classes[dev->devno] =ATA_DEV_UNKNOWN ; - rc =reset (ap, classes, deadline); + rc =reset (link, classes, deadline);if (rc)return rc;
@@ -1689,12 +1689,12 @@ static int ata_do_reset(struct ata_port *ap, ata_reset_fn_t reset,* is complete and convert all ATA_DEV_UNKNOWN to * ATA_DEV_NONE. */ -ata_link_for_each_dev (dev, &ap->link) +ata_link_for_each_dev (dev, link)if (classes[dev->devno] !=ATA_DEV_UNKNOWN )break ;if (dev) { -ata_link_for_each_dev (dev, &ap->link) { +ata_link_for_each_dev (dev, link) {if (classes[dev->devno] ==ATA_DEV_UNKNOWN ) classes[dev->devno] =ATA_DEV_NONE ; }
@@ -1715,11 +1715,10 @@ static int ata_eh_followup_srst_needed(int rc, int classify,return 0 ; } -static int ata_eh_reset (struct ata_port *ap,int classify, +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) { -struct ata_link *link = &ap->link;struct ata_eh_context *ehc = &link->eh_context;unsigned int *classes = ehc->classes;int verbose = !(ehc->i.flags &ATA_EHI_QUIET );
@@ -1745,10 +1744,10 @@ static int ata_eh_reset(struct ata_port *ap, int classify, ehc->i.action |=ATA_EH_HARDRESET ;if (prereset) { - rc =prereset (ap, jiffies +ATA_EH_PRERESET_TIMEOUT ); + rc =prereset (link, jiffies +ATA_EH_PRERESET_TIMEOUT );if (rc) {if (rc == -ENOENT ) { -ata_port_printk (ap,KERN_DEBUG , +ata_link_printk (link,KERN_DEBUG ,"port disabled. ignoring.\n" ); ehc->i.action &= ~ATA_EH_RESET_MASK ;
@@ -1757,7 +1756,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, rc =0 ; }else -ata_port_printk (ap,KERN_ERR , +ata_link_printk (link,KERN_ERR ,"prereset failed (errno=%d)\n" , rc); goto out; }
@@ -1789,7 +1788,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify,/* shut up during boot probing */ if (verbose) -ata_port_printk (ap,KERN_INFO ,"%s resetting port\n" , +ata_link_printk (link,KERN_INFO ,"%s resetting link\n" , reset == softreset ?"soft" :"hard" );/* mark that this EH session started with reset */
@@ -1798,7 +1797,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify,else ehc->i.flags |=ATA_EHI_DID_SOFTRESET ; - rc =ata_do_reset (ap, reset, classes, deadline); + rc =ata_do_reset (link, reset, classes, deadline);if (reset == hardreset &&ata_eh_followup_srst_needed (rc, classify, classes)) {
@@ -1806,7 +1805,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, reset = softreset;if (!reset) { -ata_port_printk (ap,KERN_ERR , +ata_link_printk (link,KERN_ERR ,"follow-up softreset required " "but no softreset avaliable\n" ); rc = -EINVAL ;
@@ -1814,11 +1813,11 @@ static int ata_eh_reset(struct ata_port *ap, int classify, }ata_eh_about_to_do (link,NULL ,ATA_EH_RESET_MASK ); - rc =ata_do_reset (ap, reset, classes, deadline); + rc =ata_do_reset (link, reset, classes, deadline);if (rc ==0 && classify && classes[0 ] ==ATA_DEV_UNKNOWN ) { -ata_port_printk (ap,KERN_ERR , +ata_link_printk (link,KERN_ERR ,"classification failed\n" ); rc = -EINVAL ; goto out;
@@ -1831,7 +1830,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify,if (time_before (now, deadline)) {unsigned long delta = deadline - jiffies; -ata_port_printk (ap,KERN_WARNING ,"reset failed " +ata_link_printk (link,KERN_WARNING ,"reset failed " "(errno=%d), retrying in %u secs\n" , rc, (jiffies_to_msecs (delta) +999 ) /1000 );
@@ -1860,7 +1859,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, link->sata_spd = (sstatus >>4 ) &0xf ;if (postreset) -postreset (ap, classes); +postreset (link, classes);/* reset successful, schedule revalidation */ ata_eh_done (link,NULL , ehc->i.action &ATA_EH_RESET_MASK );
@@ -2137,7 +2136,7 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,if (ehc->i.action &ATA_EH_RESET_MASK ) {ata_eh_freeze_port (ap); - rc =ata_eh_reset (ap,ata_port_nr_vacant (ap), prereset, + rc =ata_eh_reset (&ap->link,ata_port_nr_vacant (ap), prereset, softreset, hardreset, postreset);if (rc) { ata_port_printk(ap, KERN_ERR,
drivers/ata/pata_amd.c +9 -7
@@ -119,27 +119,28 @@ static void timing_setup(struct ata_port *ap, struct ata_device *adev, int offse }/** -* amd_probe_init - perform reset handling -* @ap: ATA port +* amd_pre_reset - perform reset handling +* @link: ATA link * @deadline: deadline jiffies for the operation * * Reset sequence checking enable bits to see which ports are * active. */ -static int amd_pre_reset (struct ata_port *ap,unsigned long deadline) +static int amd_pre_reset (struct ata_link *link,unsigned long deadline) {static const struct pci_bits amd_enable_bits[] = { {0x40 ,1 ,0x02 ,0x02 }, {0x40 ,1 ,0x01 ,0x01 } }; +struct ata_port *ap = link->ap;struct pci_dev *pdev =to_pci_dev (ap->host->dev);if (!pci_test_config_bits (pdev, &amd_enable_bits[ap->port_no]))return -ENOENT ; -return ata_std_prereset (ap, deadline); +return ata_std_prereset (link, deadline); }static void amd_error_handler (struct ata_port *ap)
@@ -221,25 +222,26 @@ static void amd133_set_dmamode(struct ata_port *ap, struct ata_device *adev)/** * nv_probe_init - cable detection -* @ap: ATA port +* @lin: ATA link * * Perform cable detection. The BIOS stores this in PCI config * space for us. */ -static int nv_pre_reset (struct ata_port *ap,unsigned long deadline) +static int nv_pre_reset (struct ata_link *link,unsigned long deadline) {static const struct pci_bits nv_enable_bits[] = { {0x50 ,1 ,0x02 ,0x02 }, {0x50 ,1 ,0x01 ,0x01 } }; +struct ata_port *ap = link->ap;struct pci_dev *pdev =to_pci_dev (ap->host->dev);if (!pci_test_config_bits (pdev, &nv_enable_bits[ap->port_no]))return -ENOENT ; -return ata_std_prereset (ap, deadline); +return ata_std_prereset (link, deadline); }static void nv_error_handler (struct ata_port *ap)
drivers/ata/pata_artop.c +7 -5
@@ -39,8 +39,9 @@static int clock =0 ; -static int artop6210_pre_reset (struct ata_port *ap,unsigned long deadline) +static int artop6210_pre_reset (struct ata_link *link,unsigned long deadline) { +struct ata_port *ap = link->ap;struct pci_dev *pdev =to_pci_dev (ap->host->dev);const struct pci_bits artop_enable_bits[] = { {0x4AU ,1U ,0x02UL ,0x02UL },/* port 0 */
@@ -50,7 +51,7 @@ static int artop6210_pre_reset(struct ata_port *ap, unsigned long deadline)if (!pci_test_config_bits (pdev, &artop_enable_bits[ap->port_no]))return -ENOENT ; -return ata_std_prereset (ap, deadline); +return ata_std_prereset (link, deadline); }/**
@@ -70,27 +71,28 @@ static void artop6210_error_handler(struct ata_port *ap)/** * artop6260_pre_reset - check for 40/80 pin -* @ap: Port +* @link: link * @deadline: deadline jiffies for the operation * * The ARTOP hardware reports the cable detect bits in register 0x49. * Nothing complicated needed here. */ -static int artop6260_pre_reset (struct ata_port *ap,unsigned long deadline) +static int artop6260_pre_reset (struct ata_link *link,unsigned long deadline) {static const struct pci_bits artop_enable_bits[] = { {0x4AU ,1U ,0x02UL ,0x02UL },/* port 0 */ {0x4AU ,1U ,0x04UL ,0x04UL },/* port 1 */ }; +struct ata_port *ap = link->ap;struct pci_dev *pdev =to_pci_dev (ap->host->dev);/* Odd numbered device ids are the units with enable bits (the -R cards) */ if (pdev->device %1 && !pci_test_config_bits (pdev, &artop_enable_bits[ap->port_no]))return -ENOENT ; -return ata_std_prereset (ap, deadline); +return ata_std_prereset (link, deadline); }/**
drivers/ata/pata_atiixp.c +3 -2
@@ -33,8 +33,9 @@ enum {ATIIXP_IDE_UDMA_MODE =0x56 }; -static int atiixp_pre_reset (struct ata_port *ap,unsigned long deadline) +static int atiixp_pre_reset (struct ata_link *link,unsigned long deadline) { +struct ata_port *ap = link->ap;static const struct pci_bits atiixp_enable_bits[] = { {0x48 ,1 ,0x01 ,0x00 }, {0x48 ,1 ,0x08 ,0x00 }
@@ -44,7 +45,7 @@ static int atiixp_pre_reset(struct ata_port *ap, unsigned long deadline)if (!pci_test_config_bits (pdev, &atiixp_enable_bits[ap->port_no]))return -ENOENT ; -return ata_std_prereset (ap, deadline); +return ata_std_prereset (link, deadline); }static void atiixp_error_handler (struct ata_port *ap)
drivers/ata/pata_efar.c +4 -3
@@ -26,25 +26,26 @@/** * efar_pre_reset - Enable bits -* @ap: Port +* @link: ATA link * @deadline: deadline jiffies for the operation * * Perform cable detection for the EFAR ATA interface. This is * different to the PIIX arrangement */ -static int efar_pre_reset (struct ata_port *ap,unsigned long deadline) +static int efar_pre_reset (struct ata_link *link,unsigned long deadline) {static const struct pci_bits efar_enable_bits[] = { {0x41U ,1U ,0x80UL ,0x80UL },/* port 0 */ {0x43U ,1U ,0x80UL ,0x80UL },/* port 1 */ }; +struct ata_port *ap = link->ap;struct pci_dev *pdev =to_pci_dev (ap->host->dev);if (!pci_test_config_bits (pdev, &efar_enable_bits[ap->port_no]))return -ENOENT ; -return ata_std_prereset (ap, deadline); +return ata_std_prereset (link, deadline); }/**
drivers/ata/pata_hpt37x.c +7 -5
@@ -306,15 +306,16 @@ static unsigned long hpt370a_filter(struct ata_device *adev, unsigned long mask)/** * hpt37x_pre_reset - reset the hpt37x bus -* @ap: ATA port to reset +* @link: ATA link to reset * @deadline: deadline jiffies for the operation * * Perform the initial reset handling for the 370/372 and 374 func 0 */ -static int hpt37x_pre_reset (struct ata_port *ap,unsigned long deadline) +static int hpt37x_pre_reset (struct ata_link *link,unsigned long deadline) {u8 scr2, ata66; +struct ata_port *ap = link->ap;struct pci_dev *pdev =to_pci_dev (ap->host->dev);static const struct pci_bits hpt37x_enable_bits[] = { {0x50 ,1 ,0x04 ,0x04 },
@@ -339,7 +340,7 @@ static int hpt37x_pre_reset(struct ata_port *ap, unsigned long deadline)pci_write_config_byte (pdev,0x50 +4 * ap->port_no,0x37 );udelay (100 ); -return ata_std_prereset (ap, deadline); +return ata_std_prereset (link, deadline); }/**
@@ -354,7 +355,7 @@ static void hpt37x_error_handler(struct ata_port *ap)ata_bmdma_drive_eh (ap, hpt37x_pre_reset, ata_std_softreset,NULL , ata_std_postreset); } -static int hpt374_pre_reset (struct ata_port *ap,unsigned long deadline) +static int hpt374_pre_reset (struct ata_link *link,unsigned long deadline) {static const struct pci_bits hpt37x_enable_bits[] = { {0x50 ,1 ,0x04 ,0x04 },
@@ -362,6 +363,7 @@ static int hpt374_pre_reset(struct ata_port *ap, unsigned long deadline) };u16 mcr3, mcr6;u8 ata66; +struct ata_port *ap = link->ap;struct pci_dev *pdev =to_pci_dev (ap->host->dev);if (!pci_test_config_bits (pdev, &hpt37x_enable_bits[ap->port_no]))
@@ -389,7 +391,7 @@ static int hpt374_pre_reset(struct ata_port *ap, unsigned long deadline)pci_write_config_byte (pdev,0x50 +4 * ap->port_no,0x37 );udelay (100 ); -return ata_std_prereset (ap, deadline); +return ata_std_prereset (link, deadline); }/**
drivers/ata/pata_hpt3x2n.c +4 -3
@@ -141,21 +141,22 @@ static int hpt3x2n_cable_detect(struct ata_port *ap)/** * hpt3x2n_pre_reset - reset the hpt3x2n bus -* @ap: ATA port to reset +* @link: ATA link to reset * @deadline: deadline jiffies for the operation * * Perform the initial reset handling for the 3x2n series controllers. * Reset the hardware and state machine, */ -static int hpt3xn_pre_reset (struct ata_port *ap,unsigned long deadline) +static int hpt3xn_pre_reset (struct ata_link *link,unsigned long deadline) { +struct ata_port *ap = link->ap;struct pci_dev *pdev =to_pci_dev (ap->host->dev);/* Reset the state machine */ pci_write_config_byte (pdev,0x50 +4 * ap->port_no,0x37 );udelay (100 ); -return ata_std_prereset (ap, deadline); +return ata_std_prereset (link, deadline); }/**
drivers/ata/pata_it8213.c +4 -3
@@ -23,23 +23,24 @@/** * it8213_pre_reset - check for 40/80 pin -* @ap: Port +* @link: link * @deadline: deadline jiffies for the operation * * Filter out ports by the enable bits before doing the normal reset * and probe. */ -static int it8213_pre_reset (struct ata_port *ap,unsigned long deadline) +static int it8213_pre_reset (struct ata_link *link,unsigned long deadline) {static const struct pci_bits it8213_enable_bits[] = { {0x41U ,1U ,0x80UL ,0x80UL },/* port 0 */ }; +struct ata_port *ap = link->ap;struct pci_dev *pdev =to_pci_dev (ap->host->dev);if (!pci_test_config_bits (pdev, &it8213_enable_bits[ap->port_no]))return -ENOENT ; -return ata_std_prereset (ap, deadline); +return ata_std_prereset (link, deadline); }/**
drivers/ata/pata_jmicron.c +4 -4
@@ -29,7 +29,7 @@ typedef enum {/** * jmicron_pre_reset - check for 40/80 pin -* @ap: Port +* @link: ATA link * @deadline: deadline jiffies for the operation * * Perform the PATA port setup we need.
@@ -39,9 +39,9 @@ typedef enum {* and setup here. We assume that has been done by init_one and the * BIOS. */ - -static int jmicron_pre_reset (struct ata_port *ap,unsigned long deadline) +static int jmicron_pre_reset (struct ata_link *link,unsigned long deadline) { +struct ata_port *ap = link->ap;struct pci_dev *pdev =to_pci_dev (ap->host->dev);u32 control;u32 control5;
@@ -103,7 +103,7 @@ static int jmicron_pre_reset(struct ata_port *ap, unsigned long deadline) ap->cbl =ATA_CBL_SATA ;break ; } -return ata_std_prereset (ap, deadline); +return ata_std_prereset (link, deadline); }/**
drivers/ata/pata_marvell.c +4 -3
@@ -24,14 +24,15 @@/** * marvell_pre_reset - check for 40/80 pin -* @ap: Port +* @link: link * @deadline: deadline jiffies for the operation * * Perform the PATA port setup we need. */ -static int marvell_pre_reset (struct ata_port *ap,unsigned long deadline) +static int marvell_pre_reset (struct ata_link *link,unsigned long deadline) { +struct ata_port *ap = link->ap;struct pci_dev *pdev =to_pci_dev (ap->host->dev);u32 devices;void __iomem *barp;
@@ -54,7 +55,7 @@ static int marvell_pre_reset(struct ata_port *ap, unsigned long deadline) (!(devices & 0x10))) /* PATA enable ? */return -ENOENT ; -return ata_std_prereset (ap, deadline); +return ata_std_prereset (link, deadline); }static int marvell_cable_detect (struct ata_port *ap)
drivers/ata/pata_mpiix.c +3 -2
@@ -46,15 +46,16 @@ enum { SECONDARY = (1 << 14) }; -static int mpiix_pre_reset (struct ata_port *ap,unsigned long deadline) +static int mpiix_pre_reset (struct ata_link *link,unsigned long deadline) { +struct ata_port *ap = link->ap;struct pci_dev *pdev =to_pci_dev (ap->host->dev);static const struct pci_bits mpiix_enable_bits = {0x6D ,1 ,0x80 ,0x80 };if (!pci_test_config_bits (pdev, &mpiix_enable_bits))return -ENOENT ; -return ata_std_prereset (ap, deadline); +return ata_std_prereset (link, deadline); }/**
drivers/ata/pata_ns87410.c +4 -3
@@ -32,14 +32,15 @@/** * ns87410_pre_reset - probe begin -* @ap: ATA port +* @link: ATA link * @deadline: deadline jiffies for the operation * * Check enabled ports */ -static int ns87410_pre_reset (struct ata_port *ap,unsigned long deadline) +static int ns87410_pre_reset (struct ata_link *link,unsigned long deadline) { +struct ata_port *ap = link->ap;struct pci_dev *pdev =to_pci_dev (ap->host->dev);static const struct pci_bits ns87410_enable_bits[] = { {0x43 ,1 ,0x08 ,0x08 },
@@ -49,7 +50,7 @@ static int ns87410_pre_reset(struct ata_port *ap, unsigned long deadline)if (!pci_test_config_bits (pdev, &ns87410_enable_bits[ap->port_no]))return -ENOENT ; -return ata_std_prereset (ap, deadline); +return ata_std_prereset (link, deadline); }/**
drivers/ata/pata_oldpiix.c +4 -3
@@ -29,14 +29,15 @@/** * oldpiix_pre_reset - probe begin -* @ap: ATA port +* @link: ATA link * @deadline: deadline jiffies for the operation * * Set up cable type and use generic probe init */ -static int oldpiix_pre_reset (struct ata_port *ap,unsigned long deadline) +static int oldpiix_pre_reset (struct ata_link *link,unsigned long deadline) { +struct ata_port *ap = link->ap;struct pci_dev *pdev =to_pci_dev (ap->host->dev);static const struct pci_bits oldpiix_enable_bits[] = { {0x41U ,1U ,0x80UL ,0x80UL },/* port 0 */
@@ -46,7 +47,7 @@ static int oldpiix_pre_reset(struct ata_port *ap, unsigned long deadline)if (!pci_test_config_bits (pdev, &oldpiix_enable_bits[ap->port_no]))return -ENOENT ; -return ata_std_prereset (ap, deadline); +return ata_std_prereset (link, deadline); }/**
drivers/ata/pata_opti.c +4 -3
@@ -46,14 +46,15 @@ enum {/** * opti_pre_reset - probe begin -* @ap: ATA port +* @link: ATA link * @deadline: deadline jiffies for the operation * * Set up cable type and use generic probe init */ -static int opti_pre_reset (struct ata_port *ap,unsigned long deadline) +static int opti_pre_reset (struct ata_link *link,unsigned long deadline) { +struct ata_port *ap = link->ap;struct pci_dev *pdev =to_pci_dev (ap->host->dev);static const struct pci_bits opti_enable_bits[] = { {0x45 ,1 ,0x80 ,0x00 },
@@ -63,7 +64,7 @@ static int opti_pre_reset(struct ata_port *ap, unsigned long deadline)if (!pci_test_config_bits (pdev, &opti_enable_bits[ap->port_no]))return -ENOENT ; -return ata_std_prereset (ap, deadline); +return ata_std_prereset (link, deadline); }/**
drivers/ata/pata_optidma.c +4 -3
@@ -47,14 +47,15 @@ static int pci_clock; /* 0 = 33 1 = 25 *//** * optidma_pre_reset - probe begin -* @ap: ATA port +* @link: ATA link * @deadline: deadline jiffies for the operation * * Set up cable type and use generic probe init */ -static int optidma_pre_reset (struct ata_port *ap,unsigned long deadline) +static int optidma_pre_reset (struct ata_link *link,unsigned long deadline) { +struct ata_port *ap = link->ap;struct pci_dev *pdev =to_pci_dev (ap->host->dev);static const struct pci_bits optidma_enable_bits = {0x40 ,1 ,0x08 ,0x00
@@ -63,7 +64,7 @@ static int optidma_pre_reset(struct ata_port *ap, unsigned long deadline)if (ap->port_no && !pci_test_config_bits (pdev, &optidma_enable_bits))return -ENOENT ; -return ata_std_prereset (ap, deadline); +return ata_std_prereset (link, deadline); }/**
drivers/ata/pata_pdc2027x.c +4 -4
@@ -300,7 +300,7 @@ static inline int pdc2027x_port_enabled(struct ata_port *ap)/** * pdc2027x_prereset - prereset for PATA host controller -* @ap: Target port +* @link: Target link * @deadline: deadline jiffies for the operation * * Probeinit including cable detection.
@@ -309,12 +309,12 @@ static inline int pdc2027x_port_enabled(struct ata_port *ap)* None (inherited from caller). */ -static int pdc2027x_prereset (struct ata_port *ap,unsigned long deadline) +static int pdc2027x_prereset (struct ata_link *link,unsigned long deadline) {/* Check whether port enabled */ -if (!pdc2027x_port_enabled (ap)) +if (!pdc2027x_port_enabled (link->ap))return -ENOENT ; -return ata_std_prereset (ap, deadline); +return ata_std_prereset (link, deadline); }/**
drivers/ata/pata_sil680.c +4 -3
@@ -95,15 +95,16 @@ static int sil680_cable_detect(struct ata_port *ap) {/** * sil680_bus_reset - reset the SIL680 bus -* @ap: ATA port to reset +* @link: ATA link to reset * @deadline: deadline jiffies for the operation * * Perform the SIL680 housekeeping when doing an ATA bus reset */ -static int sil680_bus_reset (struct ata_port *ap,unsigned int *classes, +static int sil680_bus_reset (struct ata_link *link,unsigned int *classes,unsigned long deadline) { +struct ata_port *ap = link->ap;struct pci_dev *pdev =to_pci_dev (ap->host->dev);unsigned long addr =sil680_selreg (ap,0 );u8 reset;
@@ -112,7 +113,7 @@ static int sil680_bus_reset(struct ata_port *ap,unsigned int *classes,pci_write_config_byte (pdev, addr, reset |0x03 );udelay (25 );pci_write_config_byte (pdev, addr, reset); -return ata_std_softreset (ap, classes, deadline); +return ata_std_softreset (link, classes, deadline); }static void sil680_error_handler (struct ata_port *ap)
drivers/ata/pata_sis.c +4 -3
@@ -131,25 +131,26 @@ static int sis_66_cable_detect(struct ata_port *ap)/** * sis_pre_reset - probe begin -* @ap: ATA port +* @link: ATA link * @deadline: deadline jiffies for the operation * * Set up cable type and use generic probe init */ -static int sis_pre_reset (struct ata_port *ap,unsigned long deadline) +static int sis_pre_reset (struct ata_link *link,unsigned long deadline) {static const struct pci_bits sis_enable_bits[] = { {0x4aU ,1U ,0x02UL ,0x02UL },/* port 0 */ {0x4aU ,1U ,0x04UL ,0x04UL },/* port 1 */ }; +struct ata_port *ap = link->ap;struct pci_dev *pdev =to_pci_dev (ap->host->dev);if (!pci_test_config_bits (pdev, &sis_enable_bits[ap->port_no]))return -ENOENT ; -return ata_std_prereset (ap, deadline); +return ata_std_prereset (link, deadline); }
drivers/ata/pata_sl82c105.c +4 -3
@@ -43,23 +43,24 @@ enum {/** * sl82c105_pre_reset - probe begin -* @ap: ATA port +* @link: ATA link * @deadline: deadline jiffies for the operation * * Set up cable type and use generic probe init */ -static int sl82c105_pre_reset (struct ata_port *ap,unsigned long deadline) +static int sl82c105_pre_reset (struct ata_link *link,unsigned long deadline) {static const struct pci_bits sl82c105_enable_bits[] = { {0x40 ,1 ,0x01 ,0x01 }, {0x40 ,1 ,0x10 ,0x10 } }; +struct ata_port *ap = link->ap;struct pci_dev *pdev =to_pci_dev (ap->host->dev);if (ap->port_no && !pci_test_config_bits (pdev, &sl82c105_enable_bits[ap->port_no]))return -ENOENT ; -return ata_std_prereset (ap, deadline); +return ata_std_prereset (link, deadline); }
drivers/ata/pata_triflex.c +4 -3
@@ -47,25 +47,26 @@/** * triflex_prereset - probe begin -* @ap: ATA port +* @link: ATA link * @deadline: deadline jiffies for the operation * * Set up cable type and use generic probe init */ -static int triflex_prereset (struct ata_port *ap,unsigned long deadline) +static int triflex_prereset (struct ata_link *link,unsigned long deadline) {static const struct pci_bits triflex_enable_bits[] = { {0x80 ,1 ,0x01 ,0x01 }, {0x80 ,1 ,0x02 ,0x02 } }; +struct ata_port *ap = link->ap;struct pci_dev *pdev =to_pci_dev (ap->host->dev);if (!pci_test_config_bits (pdev, &triflex_enable_bits[ap->port_no]))return -ENOENT ; -return ata_std_prereset (ap, deadline); +return ata_std_prereset (link, deadline); }
drivers/ata/pata_via.c +3 -2
@@ -183,8 +183,9 @@ static int via_cable_detect(struct ata_port *ap) {return ATA_CBL_PATA40 ; } -static int via_pre_reset (struct ata_port *ap,unsigned long deadline) +static int via_pre_reset (struct ata_link *link,unsigned long deadline) { +struct ata_port *ap = link->ap;const struct via_isa_bridge *config = ap->host->private_data;if (!(config->flags &VIA_NO_ENABLES )) {
@@ -197,7 +198,7 @@ static int via_pre_reset(struct ata_port *ap, unsigned long deadline)return -ENOENT ; } -return ata_std_prereset (ap, deadline); +return ata_std_prereset (link, deadline); }
drivers/ata/sata_inic162x.c +7 -6
@@ -417,12 +417,13 @@ static void inic_thaw(struct ata_port *ap)* SRST and SControl hardreset don't give valid signature on this * controller. Only controller specific hardreset mechanism works. */ -static int inic_hardreset (struct ata_port *ap,unsigned int *class, +static int inic_hardreset (struct ata_link *link,unsigned int *class,unsigned long deadline) { +struct ata_port *ap = link->ap;void __iomem *port_base =inic_port_base (ap);void __iomem *idma_ctl = port_base +PORT_IDMA_CTL ; -const unsigned long *timing =sata_ehc_deb_timing (&ap->link.eh_context); +const unsigned long *timing =sata_ehc_deb_timing (&link->eh_context);u16 val;int rc;
@@ -435,15 +436,15 @@ static int inic_hardreset(struct ata_port *ap, unsigned int *class,msleep (1 );writew (val & ~IDMA_CTL_RST_ATA , idma_ctl); - rc =sata_link_resume (&ap->link, timing, deadline); + rc =sata_link_resume (link, timing, deadline);if (rc) { -ata_port_printk (ap,KERN_WARNING ,"failed to resume " +ata_link_printk (link,KERN_WARNING ,"failed to resume " "link after reset (errno=%d)\n" , rc);return rc; } *class =ATA_DEV_NONE ; -if (ata_link_online (&ap->link)) { +if (ata_link_online (link)) {struct ata_taskfile tf;/* wait a while before checking status */
@@ -452,7 +453,7 @@ static int inic_hardreset(struct ata_port *ap, unsigned int *class, rc =ata_wait_ready (ap, deadline);/* link occupied, -ENODEV too is an error */ if (rc) { -ata_port_printk (ap,KERN_WARNING ,"device not ready " +ata_link_printk (link,KERN_WARNING ,"device not ready " "after hardreset (errno=%d)\n" , rc);return rc; }
drivers/ata/sata_nv.c +2 -2
@@ -1457,7 +1457,7 @@ static void nv_ck804_thaw(struct ata_port *ap)writeb (mask, mmio_base +NV_INT_ENABLE_CK804 ); } -static int nv_hardreset (struct ata_port *ap,unsigned int *class, +static int nv_hardreset (struct ata_link *link,unsigned int *class,unsigned long deadline) {unsigned int dummy;
@@ -1466,7 +1466,7 @@ static int nv_hardreset(struct ata_port *ap, unsigned int *class,* some controllers. Don't classify on hardreset. For more * info, see http://bugme.osdl.org/show_bug.cgi?id=3352 */ -return sata_std_hardreset (ap, &dummy, deadline); +return sata_std_hardreset (link, &dummy, deadline); }static void nv_error_handler (struct ata_port *ap)
drivers/ata/sata_sil24.c +11 -9
@@ -536,9 +536,10 @@ static int sil24_init_port(struct ata_port *ap)return 0 ; } -static int sil24_softreset (struct ata_port *ap,unsigned int *class, +static int sil24_softreset (struct ata_link *link,unsigned int *class,unsigned long deadline) { +struct ata_port *ap = link->ap;void __iomem *port = ap->ioaddr.cmd_addr;struct sil24_port_priv *pp = ap->private_data;struct sil24_prb *prb = &pp->cmd_block[0 ].ata.prb;
@@ -548,7 +549,7 @@ static int sil24_softreset(struct ata_port *ap, unsigned int *class,DPRINTK ("ENTER\n" ); -if (ata_link_offline (&ap->link)) { +if (ata_link_offline (link)) {DPRINTK ("PHY reports no device\n" ); *class =ATA_DEV_NONE ; goto out;
@@ -593,23 +594,24 @@ static int sil24_softreset(struct ata_port *ap, unsigned int *class,return 0 ; err: -ata_port_printk (ap,KERN_ERR ,"softreset failed (%s)\n" , reason); +ata_link_printk (link,KERN_ERR ,"softreset failed (%s)\n" , reason);return -EIO ; } -static int sil24_hardreset (struct ata_port *ap,unsigned int *class, +static int sil24_hardreset (struct ata_link *link,unsigned int *class,unsigned long deadline) { +struct ata_port *ap = link->ap;void __iomem *port = ap->ioaddr.cmd_addr;const char *reason;int tout_msec, rc;u32 tmp;/* sil24 does the right thing(tm) without any protection */ -sata_set_spd (&ap->link); +sata_set_spd (link); tout_msec =100 ; -if (ata_link_online (&ap->link)) +if (ata_link_online (link)) tout_msec =5000 ;writel (PORT_CS_DEV_RST , port +PORT_CTRL_STAT );
@@ -619,14 +621,14 @@ static int sil24_hardreset(struct ata_port *ap, unsigned int *class,/* SStatus oscillates between zero and valid status after * DEV_RST, debounce it. */ - rc =sata_link_debounce (&ap->link, sata_deb_timing_long, deadline); + rc =sata_link_debounce (link, sata_deb_timing_long, deadline);if (rc) { reason ="PHY debouncing failed" ; goto err; }if (tmp &PORT_CS_DEV_RST ) { -if (ata_link_offline (&ap->link)) +if (ata_link_offline (link))return 0 ; reason ="link not ready" ; goto err;
@@ -641,7 +643,7 @@ static int sil24_hardreset(struct ata_port *ap, unsigned int *class,return -EAGAIN ; err: -ata_port_printk (ap,KERN_ERR ,"hardreset failed (%s)\n" , reason); +ata_link_printk (link,KERN_ERR ,"hardreset failed (%s)\n" , reason);return -EIO ; }
drivers/ata/sata_via.c +3 -2
@@ -276,7 +276,7 @@ static void svia_noop_freeze(struct ata_port *ap)/** * vt6420_prereset - prereset for vt6420 -* @ap: target ATA port +* @link: target ATA link * @deadline: deadline jiffies for the operation * * SCR registers on vt6420 are pieces of shit and may hang the
@@ -294,8 +294,9 @@ static void svia_noop_freeze(struct ata_port *ap)* RETURNS: * 0 on success, -errno otherwise. */ -static int vt6420_prereset (struct ata_port *ap,unsigned long deadline) +static int vt6420_prereset (struct ata_link *link,unsigned long deadline) { +struct ata_port *ap = link->ap;struct ata_eh_context *ehc = &ap->link.eh_context;unsigned long timeout = jiffies + (HZ *5 );u32 sstatus, scontrol;
include/linux/libata.h +10 -9
@@ -330,14 +330,15 @@ enum ata_completion_errors {struct scsi_device ;struct ata_port_operations ;struct ata_port ; +struct ata_link ;struct ata_queued_cmd ;/* typedefs */ typedef void (*ata_qc_cb_t ) (struct ata_queued_cmd *qc); -typedef int (*ata_prereset_fn_t )(struct ata_port *ap,unsigned long deadline); -typedef int (*ata_reset_fn_t )(struct ata_port *ap,unsigned int *classes, +typedef int (*ata_prereset_fn_t )(struct ata_link *link,unsigned long deadline); +typedef int (*ata_reset_fn_t )(struct ata_link *link,unsigned int *classes,unsigned long deadline); -typedef void (*ata_postreset_fn_t )(struct ata_port *ap,unsigned int *classes); +typedef void (*ata_postreset_fn_t )(struct ata_link *link,unsigned int *classes);struct ata_ioports {void __iomem *cmd_addr;
@@ -702,14 +703,14 @@ extern int sata_link_debounce(struct ata_link *link, const unsigned long *params, unsigned long deadline);extern int sata_link_resume (struct ata_link *link,const unsigned long *params,unsigned long deadline); -extern int ata_std_prereset (struct ata_port *ap,unsigned long deadline); -extern int ata_std_softreset (struct ata_port *ap,unsigned int *classes, +extern int ata_std_prereset (struct ata_link *link,unsigned long deadline); +extern int ata_std_softreset (struct ata_link *link,unsigned int *classes,unsigned long deadline); -extern int sata_port_hardreset (struct ata_port *ap,const unsigned long *timing, -unsigned long deadline); -extern int sata_std_hardreset (struct ata_port *ap,unsigned int *class, +extern int sata_link_hardreset (struct ata_link *link, +const unsigned long *timing,unsigned long deadline); +extern int sata_std_hardreset (struct ata_link *link,unsigned int *class,unsigned long deadline); -extern void ata_std_postreset (struct ata_port *ap,unsigned int *classes); +extern void ata_std_postreset (struct ata_link *link,unsigned int *classes);extern void ata_port_disable (struct ata_port *);extern void ata_std_ports (struct ata_ioports *ioaddr);#ifdef CONFIG_PCI
Signature · 1 line
1.5.0.3
PATCH 8/16 libata-link: linkify config/EH related functions
In reply to Tejun HeoMake the following functions deal with ata_link instead of ata_port.
* ata_set_mode()
* ata_eh_autopsy() and related functions
* ata_eh_report() and related functions
* suspend/resume related functions
* ata_eh_recover() and related functions
--- drivers/ata/ata_generic.c | 7 ++- drivers/ata/libata-core.c | 18 ++++--- drivers/ata/libata-eh.c | 121 ++++++++++++++++++++++-------------------- drivers/ata/libata.h | 2 +- drivers/ata/pata_it821x.c | 6 +- drivers/ata/pata_ixp4xx_cf.c | 4 +- drivers/ata/pata_legacy.c | 6 +- drivers/ata/pata_optidma.c | 11 ++-- drivers/ata/pata_pcmcia.c | 12 ++-- drivers/ata/pata_pdc2027x.c | 11 ++-- drivers/ata/pata_platform.c | 4 +- drivers/ata/pata_rz1000.c | 6 +- drivers/ata/sata_sil.c | 16 +++--- include/linux/libata.h | 4 +- 14 files changed, 119 insertions(+), 109 deletions(-)
drivers/ata/ata_generic.c +4 -3
@@ -34,7 +34,7 @@/** * generic_set_mode - mode setting -* @ap: interface to set up +* @link: link to set up * @unused: returned device on error * * Use a non standard set_mode function. We don't want to be tuned.
@@ -43,8 +43,9 @@* and respect them. */ -static int generic_set_mode (struct ata_port *ap,struct ata_device **unused) +static int generic_set_mode (struct ata_link *link,struct ata_device **unused) { +struct ata_port *ap = link->ap;int dma_enabled =0 ;struct ata_device *dev;
@@ -52,7 +53,7 @@ static int generic_set_mode(struct ata_port *ap, struct ata_device **unused)if (ap->ioaddr.bmdma_addr) dma_enabled =ioread8 (ap->ioaddr.bmdma_addr +ATA_DMA_CMD ); -ata_link_for_each_dev (dev, &ap->link) { +ata_link_for_each_dev (dev, link) {if (ata_dev_enabled (dev)) {/* We don't really care */ dev->pio_mode =XFER_PIO_0 ;
drivers/ata/libata-core.c +10 -8
@@ -2194,7 +2194,7 @@ int ata_bus_probe(struct ata_port *ap) }/* configure transfer mode */ - rc =ata_set_mode (ap, &dev); + rc =ata_set_mode (&ap->link, &dev);if (rc) goto fail;
@@ -2805,7 +2805,7 @@ static int ata_dev_set_mode(struct ata_device *dev)/** * ata_do_set_mode - Program timings and issue SET FEATURES - XFER -* @ap: port on which timings will be programmed +* @link: link on which timings will be programmed * @r_failed_dev: out paramter for failed device * * Standard implementation of the function used to tune and set
@@ -2820,9 +2820,9 @@ static int ata_dev_set_mode(struct ata_device *dev)* 0 on success, negative errno otherwise */ -int ata_do_set_mode (struct ata_port *ap,struct ata_device **r_failed_dev) +int ata_do_set_mode (struct ata_link *link,struct ata_device **r_failed_dev) { -struct ata_link *link = &ap->link; +struct ata_port *ap = link->ap;struct ata_device *dev;int rc =0 , used_dma =0 , found =0 ;
@@ -2900,7 +2900,7 @@ int ata_do_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)/** * ata_set_mode - Program timings and issue SET FEATURES - XFER -* @ap: port on which timings will be programmed +* @link: link on which timings will be programmed * @r_failed_dev: out paramter for failed device * * Set ATA device disk transfer mode (PIO3, UDMA6, etc.). If
@@ -2913,12 +2913,14 @@ int ata_do_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev)* RETURNS: * 0 on success, negative errno otherwise */ -int ata_set_mode (struct ata_port *ap,struct ata_device **r_failed_dev) +int ata_set_mode (struct ata_link *link,struct ata_device **r_failed_dev) { +struct ata_port *ap = link->ap; +/* has private set_mode? */ if (ap->ops->set_mode) -return ap->ops->set_mode (ap, r_failed_dev); -return ata_do_set_mode (ap, r_failed_dev); +return ap->ops->set_mode (link, r_failed_dev); +return ata_do_set_mode (link, r_failed_dev); }/**
drivers/ata/libata-eh.c +63 -58
353 lines not on this page · raw message
drivers/ata/libata.h +1 -1
@@ -81,7 +81,7 @@ 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);extern int ata_down_xfermask_limit (struct ata_device *dev,unsigned int sel); -extern int ata_set_mode (struct ata_port *ap,struct ata_device **r_failed_dev); +extern int ata_set_mode (struct ata_link *link,struct ata_device **r_failed_dev);extern void ata_sg_clean (struct ata_queued_cmd *qc);extern void ata_qc_free (struct ata_queued_cmd *qc);extern void ata_qc_issue (struct ata_queued_cmd *qc);
drivers/ata/pata_it821x.c +3 -3
@@ -450,7 +450,7 @@ static unsigned int it821x_passthru_qc_issue_prot(struct ata_queued_cmd *qc)/** * it821x_smart_set_mode - mode setting -* @ap: interface to set up +* @link: interface to set up * @unused: device that failed (error only) * * Use a non standard set_mode function. We don't want to be tuned.
@@ -459,11 +459,11 @@ static unsigned int it821x_passthru_qc_issue_prot(struct ata_queued_cmd *qc)* and respect them. */ -static int it821x_smart_set_mode (struct ata_port *ap,struct ata_device **unused) +static int it821x_smart_set_mode (struct ata_link *link,struct ata_device **unused) {struct ata_device *dev; -ata_link_for_each_dev (dev, &ap->link) { +ata_link_for_each_dev (dev, link) {if (ata_dev_enabled (dev)) {/* We don't really care */ dev->pio_mode =XFER_PIO_0 ;
drivers/ata/pata_ixp4xx_cf.c +2 -2
@@ -26,11 +26,11 @@#define DRV_NAME "pata_ixp4xx_cf"#define DRV_VERSION "0.2" -static int ixp4xx_set_mode (struct ata_port *ap,struct ata_device **error) +static int ixp4xx_set_mode (struct ata_link *link,struct ata_device **error) {struct ata_device *dev; -ata_link_for_each_dev (dev, &ap->link) { +ata_link_for_each_dev (dev, link) {if (ata_dev_enabled (dev)) {ata_dev_printk (dev,KERN_INFO ,"configured for PIO0\n" ); dev->pio_mode =XFER_PIO_0 ;
drivers/ata/pata_legacy.c +3 -3
@@ -96,7 +96,7 @@ static int iordy_mask = 0xFFFFFFFF; /* Use iordy if available *//** * legacy_set_mode - mode setting -* @ap: IDE interface +* @link: IDE link * @unused: Device that failed when error is returned * * Use a non standard set_mode function. We don't want to be tuned.
@@ -107,11 +107,11 @@ static int iordy_mask = 0xFFFFFFFF; /* Use iordy if available */* expand on this as per hdparm in the base kernel. */ -static int legacy_set_mode (struct ata_port *ap,struct ata_device **unused) +static int legacy_set_mode (struct ata_link *link,struct ata_device **unused) {struct ata_device *dev; -ata_link_for_each_dev (dev, &ap->link) { +ata_link_for_each_dev (dev, link) {if (ata_dev_enabled (dev)) {ata_dev_printk (dev,KERN_INFO ,"configured for PIO\n" ); dev->pio_mode =XFER_PIO_0 ;
drivers/ata/pata_optidma.c +6 -5
@@ -324,25 +324,26 @@ static u8 optidma_make_bits43(struct ata_device *adev)/** * optidma_set_mode - mode setup -* @ap: port to set up +* @link: link to set up * * Use the standard setup to tune the chipset and then finalise the * configuration by writing the nibble of extra bits of data into * the chip. */ -static int optidma_set_mode (struct ata_port *ap,struct ata_device **r_failed) +static int optidma_set_mode (struct ata_link *link,struct ata_device **r_failed) { +struct ata_port *ap = link->ap;u8 r;int nybble =4 * ap->port_no;struct pci_dev *pdev =to_pci_dev (ap->host->dev); -int rc =ata_do_set_mode (ap, r_failed); +int rc =ata_do_set_mode (link, r_failed);if (rc ==0 ) {pci_read_config_byte (pdev,0x43 , &r); r &= (0x0F << nybble); - r |= (optidma_make_bits43 (&ap->link.device[0 ]) + - (optidma_make_bits43 (&ap->link.device[0 ]) <<2 )) << nybble; + r |= (optidma_make_bits43 (&link->device[0 ]) + + (optidma_make_bits43 (&link->device[0 ]) <<2 )) << nybble;pci_write_config_byte (pdev,0x43 , r); }return rc;
drivers/ata/pata_pcmcia.c +6 -6
@@ -56,7 +56,7 @@ struct ata_pcmcia_info {/** * pcmcia_set_mode - PCMCIA specific mode setup -* @ap: Port +* @link: link * @r_failed_dev: Return pointer for failed device * * Perform the tuning and setup of the devices and timings, which
@@ -65,13 +65,13 @@ struct ata_pcmcia_info {* decode, which alas is embarrassingly common in the PC world */ -static int pcmcia_set_mode (struct ata_port *ap,struct ata_device **r_failed_dev) +static int pcmcia_set_mode (struct ata_link *link,struct ata_device **r_failed_dev) { -struct ata_device *master = &ap->link.device[0 ]; -struct ata_device *slave = &ap->link.device[1 ]; +struct ata_device *master = &link->device[0 ]; +struct ata_device *slave = &link->device[1 ];if (!ata_dev_enabled (master) || !ata_dev_enabled (slave)) -return ata_do_set_mode (ap, r_failed_dev); +return ata_do_set_mode (link, r_failed_dev);if (memcmp (master->id +ATA_ID_FW_REV , slave->id +ATA_ID_FW_REV ,ATA_ID_FW_REV_LEN +ATA_ID_PROD_LEN ) ==0 )
@@ -84,7 +84,7 @@ static int pcmcia_set_mode(struct ata_port *ap, struct ata_device **r_failed_devata_dev_disable (slave); } } -return ata_do_set_mode (ap, r_failed_dev); +return ata_do_set_mode (link, r_failed_dev); }static struct scsi_host_template pcmcia_sht = {
drivers/ata/pata_pdc2027x.c +6 -5
@@ -69,7 +69,7 @@ static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev);static int pdc2027x_check_atapi_dma (struct ata_queued_cmd *qc);static unsigned long pdc2027x_mode_filter (struct ata_device *adev,unsigned long mask);static int pdc2027x_cable_detect (struct ata_port *ap); -static int pdc2027x_set_mode (struct ata_port *ap,struct ata_device **r_failed); +static int pdc2027x_set_mode (struct ata_link *link,struct ata_device **r_failed);/* * ATA Timing Tables based on 133MHz controller clock.
@@ -470,23 +470,24 @@ static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev)/** * pdc2027x_set_mode - Set the timing registers back to correct values. -* @ap: Port to configure +* @link: link to configure * @r_failed: Returned device for failure * * The pdc2027x hardware will look at "SET FEATURES" and change the timing registers * automatically. The values set by the hardware might be incorrect, under 133Mhz PLL. * This function overwrites the possibly incorrect values set by the hardware to be correct. */ -static int pdc2027x_set_mode (struct ata_port *ap,struct ata_device **r_failed) +static int pdc2027x_set_mode (struct ata_link *link,struct ata_device **r_failed) { +struct ata_port *ap = link->ap;struct ata_device *dev;int rc; - rc =ata_do_set_mode (ap, r_failed); + rc =ata_do_set_mode (link, r_failed);if (rc <0 )return rc; -ata_link_for_each_dev (dev, &ap->link) { +ata_link_for_each_dev (dev, link) {if (ata_dev_enabled (dev)) {pdc2027x_set_piomode (ap, dev);
drivers/ata/pata_platform.c +2 -2
@@ -30,11 +30,11 @@ static int pio_mask = 1;* Provide our own set_mode() as we don't want to change anything that has * already been configured.. */ -static int pata_platform_set_mode (struct ata_port *ap,struct ata_device **unused) +static int pata_platform_set_mode (struct ata_link *link,struct ata_device **unused) {struct ata_device *dev; -ata_link_for_each_dev (dev, &ap->link) { +ata_link_for_each_dev (dev, link) {if (ata_dev_enabled (dev)) {/* We don't really care */ dev->pio_mode = dev->xfer_mode =XFER_PIO_0 ;
drivers/ata/pata_rz1000.c +3 -3
@@ -26,7 +26,7 @@/** * rz1000_set_mode - mode setting function -* @ap: ATA interface +* @link: ATA link * @unused: returned device on set_mode failure * * Use a non standard set_mode function. We don't want to be tuned. We
@@ -34,11 +34,11 @@* whacked out. */ -static int rz1000_set_mode (struct ata_port *ap,struct ata_device **unused) +static int rz1000_set_mode (struct ata_link *link,struct ata_device **unused) {struct ata_device *dev; -ata_link_for_each_dev (dev, &ap->link) { +ata_link_for_each_dev (dev, link) {if (ata_dev_enabled (dev)) {/* We don't really care */ dev->pio_mode =XFER_PIO_0 ;
drivers/ata/sata_sil.c +8 -8
@@ -117,7 +117,7 @@ static int sil_pci_device_resume(struct pci_dev *pdev);static void sil_dev_config (struct ata_device *dev);static int sil_scr_read (struct ata_port *ap,unsigned int sc_reg,u32 *val);static int sil_scr_write (struct ata_port *ap,unsigned int sc_reg,u32 val); -static int sil_set_mode (struct ata_port *ap,struct ata_device **r_failed); +static int sil_set_mode (struct ata_link *link,struct ata_device **r_failed);static void sil_freeze (struct ata_port *ap);static void sil_thaw (struct ata_port *ap);
@@ -290,27 +290,27 @@ static unsigned char sil_get_device_cache_line(struct pci_dev *pdev)/** * sil_set_mode - wrap set_mode functions -* @ap: port to set up +* @link: link to set up * @r_failed: returned device when we fail * * Wrap the libata method for device setup as after the setup we need * to inspect the results and do some configuration work */ -static int sil_set_mode (struct ata_port *ap,struct ata_device **r_failed) +static int sil_set_mode (struct ata_link *link,struct ata_device **r_failed) { -struct ata_host *host = ap->host; -struct ata_device *dev; -void __iomem *mmio_base = host->iomap[SIL_MMIO_BAR ]; +struct ata_port *ap = link->ap; +void __iomem *mmio_base = ap->host->iomap[SIL_MMIO_BAR ];void __iomem *addr = mmio_base + sil_port[ap->port_no].xfer_mode; +struct ata_device *dev;u32 tmp, dev_mode[2 ] = { };int rc; - rc =ata_do_set_mode (ap, r_failed); + rc =ata_do_set_mode (link, r_failed);if (rc)return rc; -ata_link_for_each_dev (dev, &ap->link) { +ata_link_for_each_dev (dev, link) {if (!ata_dev_enabled (dev)) dev_mode[dev->devno] =0 ;/* PIO0/1/2 */ else if (dev->flags &ATA_DFLAG_PIO )
include/linux/libata.h +2 -2
@@ -603,7 +603,7 @@ struct ata_port_operations {void (*dev_select)(struct ata_port *ap,unsigned int device);void (*phy_reset) (struct ata_port *ap);/* obsolete */ -int (*set_mode) (struct ata_port *ap,struct ata_device **r_failed_dev); +int (*set_mode) (struct ata_link *link,struct ata_device **r_failed_dev);int (*cable_detect) (struct ata_port *ap);
@@ -833,7 +833,7 @@ extern void ata_scsi_slave_destroy(struct scsi_device *sdev);extern int ata_scsi_change_queue_depth (struct scsi_device *sdev,int queue_depth);extern struct ata_device *ata_dev_pair (struct ata_device *adev); -extern int ata_do_set_mode (struct ata_port *ap,struct ata_device **r_failed_dev); +extern int ata_do_set_mode (struct ata_link *link,struct ata_device **r_failed_dev);extern u8 ata_irq_on (struct ata_port *ap);extern u8 ata_dummy_irq_on (struct ata_port *ap);extern u8 ata_irq_ack (struct ata_port *ap,unsigned int chk_drq);
Signature · 1 line
1.5.0.3
PATCH 9/16 libata-link: make two port flags HRST_TO_RESUME and SKIP_D2H_BSY link flags
In reply to Tejun HeoHRST_TO_RESUME and SKIP_D2H_BSY are link attributes. Move them to ata_link->flags. This will allow host and PMP links to have different attributes. ata_port_info->link_flags is added and used by LLDs to specify these flags during initialization.
--- drivers/ata/ahci.c | 10 +++++++--- drivers/ata/libata-core.c | 5 +++-- drivers/ata/sata_nv.c | 14 +++++++------- drivers/ata/sata_sil.c | 7 ++++++- drivers/ata/sata_sil24.c | 7 +++++-- include/linux/libata.h | 11 ++++++++--- 6 files changed, 36 insertions(+), 18 deletions(-)
drivers/ata/ahci.c +7 -3
@@ -175,8 +175,8 @@ enum {AHCI_FLAG_COMMON =ATA_FLAG_SATA |ATA_FLAG_NO_LEGACY |ATA_FLAG_MMIO |ATA_FLAG_PIO_DMA | -ATA_FLAG_SKIP_D2H_BSY |ATA_FLAG_ACPI_SATA , + AHCI_LFLAG_COMMON = ATA_LFLAG_SKIP_D2H_BSY, }; struct ahci_cmd_hdr {
@@ -330,6 +330,7 @@ static const struct ata_port_info ahci_port_info[] = {/* board_ahci */ { .flags = AHCI_FLAG_COMMON, + .link_flags = AHCI_LFLAG_COMMON, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = 0x7f, /* udma0-6 ; FIXME */ .port_ops = &ahci_ops,
@@ -337,14 +338,15 @@ static const struct ata_port_info ahci_port_info[] = {/* board_ahci_pi */ { .flags = AHCI_FLAG_COMMON | AHCI_FLAG_HONOR_PI, + .link_flags = AHCI_LFLAG_COMMON, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = 0x7f, /* udma0-6 ; FIXME */ .port_ops = &ahci_ops, },/* board_ahci_vt8251 */ { - .flags = AHCI_FLAG_COMMON | ATA_FLAG_HRST_TO_RESUME | - AHCI_FLAG_NO_NCQ, + .flags = AHCI_FLAG_COMMON | AHCI_FLAG_NO_NCQ, + .link_flags = AHCI_LFLAG_COMMON | ATA_LFLAG_HRST_TO_RESUME, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = 0x7f, /* udma0-6 ; FIXME */ .port_ops = &ahci_vt8251_ops,
@@ -352,6 +354,7 @@ static const struct ata_port_info ahci_port_info[] = {/* board_ahci_ign_iferr */ { .flags = AHCI_FLAG_COMMON | AHCI_FLAG_IGN_IRQ_IF_ERR, + .link_flags = AHCI_LFLAG_COMMON, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = 0x7f, /* udma0-6 ; FIXME */ .port_ops = &ahci_ops,
@@ -361,6 +364,7 @@ static const struct ata_port_info ahci_port_info[] = { .flags = AHCI_FLAG_COMMON |AHCI_FLAG_IGN_SERR_INTERNAL | AHCI_FLAG_32BIT_ONLY, + .link_flags = AHCI_LFLAG_COMMON, .pio_mask = 0x1f, /* pio0-4 */ .udma_mask = 0x7f, /* udma0-6 ; FIXME */ .port_ops = &ahci_ops,
drivers/ata/libata-core.c +3 -2
@@ -3358,7 +3358,7 @@ int ata_std_prereset(struct ata_link *link, unsigned long deadline)/* handle link resume */ if ((ehc->i.flags &ATA_EHI_RESUME_LINK ) && - (ap->flags &ATA_FLAG_HRST_TO_RESUME )) + (link->flags &ATA_LFLAG_HRST_TO_RESUME )) ehc->i.action |=ATA_EH_HARDRESET ;/* if we're about to do hardreset, nothing more to do */
@@ -3377,7 +3377,7 @@ int ata_std_prereset(struct ata_link *link, unsigned long deadline)/* Wait for !BSY if the controller can wait for the first D2H * Reg FIS and we don't know that no device is attached. */ -if (!(ap->flags &ATA_FLAG_SKIP_D2H_BSY ) && !ata_link_offline (link)) { +if (!(link->flags &ATA_LFLAG_SKIP_D2H_BSY ) && !ata_link_offline (link)) { rc =ata_wait_ready (ap, deadline);if (rc && rc != -ENODEV ) { ata_link_printk(link, KERN_WARNING, "device not ready "
@@ -6194,6 +6194,7 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev, ap->mwdma_mask = pi->mwdma_mask; ap->udma_mask = pi->udma_mask; ap->flags |= pi->flags; + ap->link.flags |= pi->link_flags; ap->ops = pi->port_ops;if (!host->ops && (pi->port_ops != &ata_dummy_port_ops))
drivers/ata/sata_nv.c +7 -7
@@ -454,8 +454,8 @@ static const struct ata_port_info nv_port_info[] = {/* generic */ { .sht = &nv_sht, - .flags =ATA_FLAG_SATA |ATA_FLAG_NO_LEGACY | - ATA_FLAG_HRST_TO_RESUME, + .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, + .link_flags = ATA_LFLAG_HRST_TO_RESUME, .pio_mask = NV_PIO_MASK, .mwdma_mask = NV_MWDMA_MASK, .udma_mask = NV_UDMA_MASK,
@@ -465,8 +465,8 @@ static const struct ata_port_info nv_port_info[] = {/* nforce2/3 */ { .sht = &nv_sht, - .flags =ATA_FLAG_SATA |ATA_FLAG_NO_LEGACY | - ATA_FLAG_HRST_TO_RESUME, + .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, + .link_flags = ATA_LFLAG_HRST_TO_RESUME, .pio_mask = NV_PIO_MASK, .mwdma_mask = NV_MWDMA_MASK, .udma_mask = NV_UDMA_MASK,
@@ -476,8 +476,8 @@ static const struct ata_port_info nv_port_info[] = {/* ck804 */ { .sht = &nv_sht, - .flags =ATA_FLAG_SATA |ATA_FLAG_NO_LEGACY | - ATA_FLAG_HRST_TO_RESUME, + .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, + .link_flags = ATA_LFLAG_HRST_TO_RESUME, .pio_mask = NV_PIO_MASK, .mwdma_mask = NV_MWDMA_MASK, .udma_mask = NV_UDMA_MASK,
@@ -488,8 +488,8 @@ static const struct ata_port_info nv_port_info[] = { { .sht = &nv_adma_sht, .flags =ATA_FLAG_SATA |ATA_FLAG_NO_LEGACY | -ATA_FLAG_HRST_TO_RESUME | ATA_FLAG_MMIO | ATA_FLAG_NCQ, + .link_flags = ATA_LFLAG_HRST_TO_RESUME, .pio_mask = NV_PIO_MASK, .mwdma_mask = NV_MWDMA_MASK, .udma_mask = NV_UDMA_MASK,
drivers/ata/sata_sil.c +6 -1
@@ -59,7 +59,8 @@ enum {SIL_FLAG_MOD15WRITE = (1 <<30 ),SIL_DFL_PORT_FLAGS =ATA_FLAG_SATA |ATA_FLAG_NO_LEGACY | - ATA_FLAG_MMIO | ATA_FLAG_HRST_TO_RESUME, +ATA_FLAG_MMIO , + SIL_DFL_LINK_FLAGS = ATA_LFLAG_HRST_TO_RESUME,/* * Controller IDs
@@ -216,6 +217,7 @@ static const struct ata_port_info sil_port_info[] = {/* sil_3112 */ { .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE, + .link_flags = SIL_DFL_LINK_FLAGS, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x3f, /* udma0-5 */
@@ -225,6 +227,7 @@ static const struct ata_port_info sil_port_info[] = { { .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE | SIL_FLAG_NO_SATA_IRQ, + .link_flags = SIL_DFL_LINK_FLAGS, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x3f, /* udma0-5 */
@@ -233,6 +236,7 @@ static const struct ata_port_info sil_port_info[] = {/* sil_3512 */ { .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT, + .link_flags = SIL_DFL_LINK_FLAGS, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x3f, /* udma0-5 */
@@ -241,6 +245,7 @@ static const struct ata_port_info sil_port_info[] = {/* sil_3114 */ { .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT, + .link_flags = SIL_DFL_LINK_FLAGS, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x3f, /* udma0-5 */
drivers/ata/sata_sil24.c +5 -2
@@ -237,8 +237,8 @@ enum {/* host flags */ SIL24_COMMON_FLAGS =ATA_FLAG_SATA |ATA_FLAG_NO_LEGACY |ATA_FLAG_MMIO |ATA_FLAG_PIO_DMA | -ATA_FLAG_NCQ |ATA_FLAG_SKIP_D2H_BSY | -ATA_FLAG_ACPI_SATA , +ATA_FLAG_NCQ |ATA_FLAG_ACPI_SATA , +SIL24_COMMON_LFLAGS =ATA_LFLAG_SKIP_D2H_BSY ,SIL24_FLAG_PCIX_IRQ_WOC = (1 <<24 ),/* IRQ loss errata on PCI-X */ IRQ_STAT_4PORTS = 0xf,
@@ -424,6 +424,7 @@ static const struct ata_port_info sil24_port_info[] = { { .flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(4) | SIL24_FLAG_PCIX_IRQ_WOC, + .link_flags = SIL24_COMMON_LFLAGS, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x3f, /* udma0-5 */
@@ -432,6 +433,7 @@ static const struct ata_port_info sil24_port_info[] = {/* sil_3132 */ { .flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(2), + .link_flags = SIL24_COMMON_LFLAGS, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x3f, /* udma0-5 */
@@ -440,6 +442,7 @@ static const struct ata_port_info sil24_port_info[] = {/* sil_3131/sil_3531 */ { .flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(1), + .link_flags = SIL24_COMMON_LFLAGS, .pio_mask = 0x1f, /* pio0-4 */ .mwdma_mask = 0x07, /* mwdma0-2 */ .udma_mask = 0x3f, /* udma0-5 */
include/linux/libata.h +8 -3
@@ -155,6 +155,11 @@ enum {ATA_DEV_ATAPI_UNSUP =4 ,/* ATAPI device (unsupported) */ ATA_DEV_NONE =5 ,/* no device */ +/* struct ata_link flags */ +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 */ +/* struct ata_port flags */ ATA_FLAG_SLAVE_POSS = (1 << 0), /* host supports slave dev *//* (doesn't imply presence) */
@@ -169,9 +174,6 @@ enum {ATA_FLAG_PIO_POLLING = (1 <<9 ),/* use polling PIO if LLD * doesn't handle PIO interrupts */ ATA_FLAG_NCQ = (1 <<10 ),/* host supports NCQ */ -ATA_FLAG_HRST_TO_RESUME = (1 <<11 ),/* hardreset to resume phy */ -ATA_FLAG_SKIP_D2H_BSY = (1 <<12 ),/* can't wait for the first D2H -* Register FIS clearing BSY */ ATA_FLAG_DEBUGMSG = (1 <<13 ),ATA_FLAG_IGN_SIMPLEX = (1 <<15 ),/* ignore SIMPLEX */ ATA_FLAG_NO_IORDY = (1 << 16), /* controller lacks iordy */
@@ -513,6 +515,8 @@ struct ata_link {unsigned int active_tag;/* active tag on this link */ u32 sactive;/* active NCQ commands */ +unsigned int flags;/* ATA_LFLAG_xxx */ +unsigned int hw_sata_spd_limit;unsigned int sata_spd_limit;unsigned int sata_spd;/* current SATA PHY speed */
@@ -650,6 +654,7 @@ struct ata_port_operations {struct ata_port_info {struct scsi_host_template *sht;unsigned long flags; +unsigned long link_flags;unsigned long pio_mask;unsigned long mwdma_mask;unsigned long udma_mask;
Signature · 1 line
1.5.0.3
PATCH 10/16 libata-link: separate out link initialization functions
In reply to Tejun HeoSeparate out link initialization into ata_link_init() and ata_link_init_sata_spd_limit().
--- drivers/ata/libata-core.c | 84 ++++++++++++++++++++++++++++++++++----------- 1 files changed, 64 insertions(+), 20 deletions(-)
drivers/ata/libata-core.c +64 -20
@@ -5986,6 +5986,68 @@ void ata_dev_init(struct ata_device *dev) }/** +* ata_link_init - Initialize an ata_link structure +* @ap: ATA port link is attached to +* @link: Link structure to initialize +* +* Initialize @link. +* +* LOCKING: +* Kernel thread context (may sleep) +*/ +static void ata_link_init (struct ata_port *ap,struct ata_link *link) +{ +int i; + +/* clear everything except for devices */ + memset(link, 0, offsetof(struct ata_link, device[0])); + + link->ap = ap; + link->active_tag =ATA_TAG_POISON ; + link->hw_sata_spd_limit =UINT_MAX ; + +/* can't use iterator, ap isn't initialized yet */ +for (i =0 ; i <ATA_MAX_DEVICES ; i++) { +struct ata_device *dev = &link->device[i]; + + dev->link = link; + dev->devno = dev - link->device; +ata_dev_init (dev); + } +} + +/** +* sata_link_init_spd_limit - Initialize link->sata_spd_limit +* @link: Link to configure sata_spd_limit for +* +* Initialize @link->[hw_]sata_spd_limit to the currently +* configured value. +* +* LOCKING: +* Kernel thread context (may sleep). +* +* RETURNS: +* 0 on success, -errno on failure. +*/ +static int sata_link_init_spd_limit (struct ata_link *link) +{ +u32 scontrol, spd; +int rc; + + rc =sata_scr_read (link,SCR_CONTROL , &scontrol); +if (rc) +return rc; + + spd = (scontrol >>4 ) &0xf ; +if (spd) + link->hw_sata_spd_limit &= (1 << spd) -1 ; + + link->sata_spd_limit = link->hw_sata_spd_limit; + +return 0 ; +} + +/** * ata_port_alloc - allocate and initialize basic ATA port resources * @host: ATA host this allocated port belongs to *
@@ -6000,7 +6062,6 @@ void ata_dev_init(struct ata_device *dev)struct ata_port *ata_port_alloc (struct ata_host *host) {struct ata_port *ap; -unsigned int i;DPRINTK ("ENTER\n" );
@@ -6015,9 +6076,6 @@ struct ata_port *ata_port_alloc(struct ata_host *host) ap->ctl =ATA_DEVCTL_OBS ; ap->host = host; ap->dev = host->dev; - - ap->link.hw_sata_spd_limit =UINT_MAX ; - ap->link.active_tag =ATA_TAG_POISON ; ap->last_ctl =0xFF ;#if defined(ATA_VERBOSE_DEBUG )
@@ -6040,15 +6098,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host) ap->cbl =ATA_CBL_NONE ; - ap->link.ap = ap; - -/* can't use iterator, ap isn't initialized yet */ -for (i =0 ; i <ATA_MAX_DEVICES ; i++) { -struct ata_device *dev = &ap->link.device[i]; - dev->link = &ap->link; - dev->devno = i; -ata_dev_init (dev); - } +ata_link_init (ap, &ap->link);#ifdef ATA_IRQ_TRAP ap->stats.unhandled_irq =1 ;
@@ -6331,7 +6381,6 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)for (i =0 ; i < host->n_ports; i++) {struct ata_port *ap = host->ports[i];int irq_line; -u32 scontrol;unsigned long xfer_mask;/* set SATA cable type if still unset */
@@ -6339,12 +6388,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht) ap->cbl =ATA_CBL_SATA ;/* init sata_spd_limit to the current value */ -if (sata_scr_read (&ap->link,SCR_CONTROL , &scontrol) ==0 ) { -int spd = (scontrol >>4 ) &0xf ; -if (spd) - ap->link.hw_sata_spd_limit &= (1 << spd) -1 ; - } - ap->link.sata_spd_limit = ap->link.hw_sata_spd_limit; +sata_link_init_spd_limit (&ap->link);/* report the secondary IRQ for second channel legacy */ irq_line = host->irq;
Signature · 1 line
1.5.0.3
Re: [PATCH 10/16] libata-link: separate out link initialization functions
Quoted 4 lines · Tejun Heo
Separate out link initialization into
ata_link_init()andata_link_init_sata_spd_limit().Signed-off-by Tejun Heo <[email protected]>
Function name too long :) Drop "_limit" perhaps.
Anyway, ACK 3-10
PATCH 11/16 libata-link: implement ata_link_abort()
In reply to Tejun HeoImplement ata_link_abort().
--- drivers/ata/libata-core.c | 1 + drivers/ata/libata-eh.c | 50 ++++++++++++++++++++++++++++++++------------ include/linux/libata.h | 1 + 3 files changed, 38 insertions(+), 14 deletions(-)
drivers/ata/libata-core.c +1 -0
@@ -6978,6 +6978,7 @@ EXPORT_SYMBOL_GPL(ata_pci_clear_simplex);EXPORT_SYMBOL_GPL (ata_eng_timeout);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 (ata_eh_freeze_port);
drivers/ata/libata-eh.c +36 -14
68 lines not on this page · raw message
include/linux/libata.h +1 -0
@@ -901,6 +901,7 @@ extern unsigned long ata_pci_default_filter(struct ata_device *, unsigned long);extern void ata_eng_timeout (struct ata_port *ap);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);
Signature · 1 line
1.5.0.3
PATCH 12/16 libata-link: add PMP links
In reply to Tejun HeoAdd link->pmp, ap->nr_pmp_links, ap->pmp_link[], and implement/update link helpers.
printk helpers are updated such that port and link are identifed as 'ataP:' if no PMP is attached, while device is identified as 'ataP.DD:'. If PMP is attached, they become 'ataP:', 'ataP.LL:' and 'ataP.LL' - ie. link and device are identified their PMP number.
If PPM is attached (ap->nr_pmp_links != 0), ata_for_each_link() iterates over PMP links, while __ata_for_each_link() iterates over the host link + PMP links. If PMP is not attached (ap->nr_pmp_links == 0), both iterate over only the host link.
--- drivers/ata/libata-core.c | 6 +++- include/linux/libata.h | 53 +++++++++++++++++++++++++++++++++++++++----- 2 files changed, 51 insertions(+), 8 deletions(-)
drivers/ata/libata-core.c +4 -2
@@ -5989,13 +5989,14 @@ void ata_dev_init(struct ata_device *dev)* ata_link_init - Initialize an ata_link structure * @ap: ATA port link is attached to * @link: Link structure to initialize +* @pmp: Port multiplier port number * * Initialize @link. * * LOCKING: * Kernel thread context (may sleep) */ -static void ata_link_init (struct ata_port *ap,struct ata_link *link) +static void ata_link_init (struct ata_port *ap,struct ata_link *link,int pmp) {int i;
@@ -6003,6 +6004,7 @@ static void ata_link_init(struct ata_port *ap, struct ata_link *link) memset(link, 0, offsetof(struct ata_link, device[0])); link->ap = ap; + link->pmp = pmp; link->active_tag =ATA_TAG_POISON ; link->hw_sata_spd_limit =UINT_MAX ;
@@ -6098,7 +6100,7 @@ struct ata_port *ata_port_alloc(struct ata_host *host) ap->cbl =ATA_CBL_NONE ; -ata_link_init (ap, &ap->link); +ata_link_init (ap, &ap->link,0 );#ifdef ATA_IRQ_TRAP ap->stats.unhandled_irq =1 ;
include/linux/libata.h +47 -6
85 lines not on this page · raw message
Signature · 1 line
1.5.0.3
PATCH 13/16 libata-link: update ata_scsi_error() to handle PMP links
In reply to Tejun HeoUpdate ata_scsi_error() to handle PMP links. As error conditions can occur on both host and PMP links, __ata_port_for_each_link() is used.
--- drivers/ata/libata-eh.c | 13 +++++++++---- 1 files changed, 9 insertions(+), 4 deletions(-)
drivers/ata/libata-eh.c +9 -4
@@ -298,6 +298,8 @@ void ata_scsi_error(struct Scsi_Host *host) repeat:/* invoke error handler */ if (ap->ops->error_handler) { +struct ata_link *link; +/* kill fast drain timer */ del_timer_sync (&ap->fastdrain_timer);
@@ -307,9 +309,11 @@ void ata_scsi_error(struct Scsi_Host *host)/* fetch & clear EH info */ spin_lock_irqsave (ap->lock, flags); -memset (&ap->link.eh_context,0 ,sizeof (ap->link.eh_context)); - ap->link.eh_context.i = ap->link.eh_info; -memset (&ap->link.eh_info,0 ,sizeof (ap->link.eh_info)); +__ata_port_for_each_link (link, ap) { +memset (&link->eh_context,0 ,sizeof (link->eh_context)); + link->eh_context.i = link->eh_info; +memset (&link->eh_info,0 ,sizeof (link->eh_info)); + } ap->pflags |=ATA_PFLAG_EH_IN_PROGRESS ; ap->pflags &= ~ATA_PFLAG_EH_PENDING ;
@@ -345,7 +349,8 @@ void ata_scsi_error(struct Scsi_Host *host) }/* this run is complete, make sure EH info is clear */ -memset (&ap->link.eh_info,0 ,sizeof (ap->link.eh_info)); +__ata_port_for_each_link (link, ap) +memset (&link->eh_info,0 ,sizeof (link->eh_info));/* Clear host_eh_scheduled while holding ap->lock such * that if exception occurs after this point but
Signature · 1 line
1.5.0.3
PATCH 14/16 libata-link: update EH to deal with PMP links
In reply to Tejun HeoUpdate ata_eh_autopsy(), ata_eh_report(), ata_eh_revalidate_and_attach() and ata_eh_recover() to deal with PMP links. ata_eh_autopsy() and ata_eh_report() updates are straightforward. They just repeat the same operation over all configured links. The only change to ata_eh_revalidate_and_attach() is avoiding calling ->cable_select() on non-host ports.
ata_eh_recover() update is more complex as it first processes all resets and then performs the rest. This is necessary as thawing with some links in unknown state can be dangerous. ehi->action is cleared on successful recovery of a link to avoid repeating recovery due to failures in other links.
ata_eh_recover() iterates over only PMP links if PMP is attached, and, on failure, the failing link is returned in @failed_link instead of disabling devices directly. These are to integrate ata_eh_recover() into PMP EH later.
--- drivers/ata/libata-eh.c | 228 ++++++++++++++++++++++++++++++++-------------- 1 files changed, 158 insertions(+), 70 deletions(-)
drivers/ata/libata-eh.c +158 -70
@@ -1513,8 +1513,8 @@ static unsigned int ata_eh_speed_down(struct ata_device *dev, int is_io, }/** -* ata_eh_autopsy - analyze error and determine recovery action -* @link: ATA link to perform autopsy on +* ata_eh_link_autopsy - analyze error and determine recovery action +* @link: host link to perform autopsy on * * Analyze why @link failed and determine which recovery actions * are needed. This function also sets more detailed AC_ERR_*
@@ -1523,7 +1523,7 @@ static unsigned int ata_eh_speed_down(struct ata_device *dev, int is_io,* LOCKING: * Kernel thread context (may sleep). */ -static void ata_eh_autopsy (struct ata_link *link) +static void ata_eh_link_autopsy (struct ata_link *link) {struct ata_port *ap = link->ap;struct ata_eh_context *ehc = &link->eh_context;
@@ -1615,7 +1615,25 @@ static void ata_eh_autopsy(struct ata_link *link) }/** -* ata_eh_report - report error handling to user +* ata_eh_autopsy - analyze error and determine recovery action +* @ap: host port to perform autopsy on +* +* Analyze all links of @ap and determine why they failed and +* which recovery actions are needed. +* +* LOCKING: +* Kernel thread context (may sleep). +*/ +static void ata_eh_autopsy (struct ata_port *ap) +{ +struct ata_link *link; + +__ata_port_for_each_link (link, ap) +ata_eh_link_autopsy (link); +} + +/** +* ata_eh_link_report - report error handling to user * @link: ATA link EH is going on * * Report EH to user.
@@ -1623,7 +1641,7 @@ static void ata_eh_autopsy(struct ata_link *link)* LOCKING: * None. */ -static void ata_eh_report (struct ata_link *link) +static void ata_eh_link_report (struct ata_link *link) {struct ata_port *ap = link->ap;struct ata_eh_context *ehc = &link->eh_context;
@@ -1702,6 +1720,23 @@ static void ata_eh_report(struct ata_link *link) } } +/** +* ata_eh_report - report error handling to user +* @ap: ATA port to report EH about +* +* Report EH to user. +* +* LOCKING: +* None. +*/ +static void ata_eh_report (struct ata_port *ap) +{ +struct ata_link *link; + +__ata_port_for_each_link (link, ap) +ata_eh_link_report (link); +} +static int ata_do_reset (struct ata_link *link,ata_reset_fn_t reset,unsigned int *classes,unsigned long deadline) {
@@ -1971,7 +2006,8 @@ static int ata_eh_revalidate_and_attach(struct ata_link *link, }/* PDIAG- should have been released, ask cable type if post-reset */ -if ((ehc->i.flags &ATA_EHI_DID_RESET ) && ap->ops->cable_detect) +if (ata_is_host_link (link) && ap->ops->cable_detect && + (ehc->i.flags &ATA_EHI_DID_RESET )) ap->cbl = ap->ops->cable_detect (ap);/* Configure new devices forward such that user doesn't see
@@ -2045,7 +2081,7 @@ static int ata_eh_skip_recovery(struct ata_link *link)return 1 ; } -static void ata_eh_handle_dev_fail (struct ata_device *dev,int err) +static int ata_eh_handle_dev_fail (struct ata_device *dev,int err) {struct ata_eh_context *ehc = &dev->link->eh_context;
@@ -2086,12 +2122,16 @@ static void ata_eh_handle_dev_fail(struct ata_device *dev, int err) ehc->did_probe_mask |= (1 << dev->devno); ehc->i.action |=ATA_EH_SOFTRESET ; } + +return 1 ; }else {/* soft didn't work? be haaaaard */ if (ehc->i.flags &ATA_EHI_DID_RESET ) ehc->i.action |=ATA_EH_HARDRESET ;else ehc->i.action |=ATA_EH_SOFTRESET ; + +return 0 ; } }
@@ -2102,12 +2142,13 @@ static void ata_eh_handle_dev_fail(struct ata_device *dev, int err)* @softreset: softreset method (can be NULL) * @hardreset: hardreset method (can be NULL) * @postreset: postreset method (can be NULL) +* @r_failed_link: out parameter for failed link * * This is the alpha and omega, eum and yang, heart and soul of * libata exception handling. On entry, actions required to -* recover the port and hotplug requests are recorded in -* eh_context. This function executes all the operations with -* appropriate retrials and fallbacks to resurrect failed +* recover each link and hotplug requests are recorded in the +* link's eh_context. This function executes all the operations +* with appropriate retrials and fallbacks to resurrect failed * devices, detach goners and greet newcomers. * * LOCKING:
@@ -2118,102 +2159,139 @@ static void ata_eh_handle_dev_fail(struct ata_device *dev, int err)*/ 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) +ata_postreset_fn_t postreset, +struct ata_link **r_failed_link) { -struct ata_link *link = &ap->link; -struct ata_eh_context *ehc = &link->eh_context; +struct ata_link *link;struct ata_device *dev; -int rc; +int nr_failed_devs, nr_disabled_devs; +int reset, rc;DPRINTK ("ENTER\n" );/* prep for recovery */ -ata_link_for_each_dev (dev, link) { - ehc->tries[dev->devno] =ATA_EH_DEV_TRIES ; +ata_port_for_each_link (link, ap) { +struct ata_eh_context *ehc = &link->eh_context; -/* collect port action mask recorded in dev actions */ - ehc->i.action |= - ehc->i.dev_action[dev->devno] & ~ATA_EH_PERDEV_MASK ; - ehc->i.dev_action[dev->devno] &=ATA_EH_PERDEV_MASK ; - -/* process hotplug request */ -if (dev->flags &ATA_DFLAG_DETACH ) -ata_eh_detach_dev (dev); +ata_link_for_each_dev (dev, link) { + ehc->tries[dev->devno] =ATA_EH_DEV_TRIES ; -if (!ata_dev_enabled (dev) && - ((ehc->i.probe_mask & (1 << dev->devno)) && - !(ehc->did_probe_mask & (1 << dev->devno)))) { -ata_eh_detach_dev (dev); -ata_dev_init (dev); - ehc->did_probe_mask |= (1 << dev->devno); - ehc->i.action |=ATA_EH_SOFTRESET ; +/* collect port action mask recorded in dev actions */ + ehc->i.action |= ehc->i.dev_action[dev->devno] & + ~ATA_EH_PERDEV_MASK ; + ehc->i.dev_action[dev->devno] &=ATA_EH_PERDEV_MASK ; + +/* process hotplug request */ +if (dev->flags &ATA_DFLAG_DETACH ) +ata_eh_detach_dev (dev); + +if (!ata_dev_enabled (dev) && + ((ehc->i.probe_mask & (1 << dev->devno)) && + !(ehc->did_probe_mask & (1 << dev->devno)))) { +ata_eh_detach_dev (dev); +ata_dev_init (dev); + ehc->did_probe_mask |= (1 << dev->devno); + ehc->i.action |=ATA_EH_SOFTRESET ; + } } } retry: rc =0 ; + nr_failed_devs =0 ; + nr_disabled_devs =0 ; + reset =0 ;/* if UNLOADING, finish immediately */ if (ap->pflags &ATA_PFLAG_UNLOADING ) goto out; -/* skip EH if possible. */ -if (ata_eh_skip_recovery (link)) - ehc->i.action =0 ; +/* prep for EH */ +ata_port_for_each_link (link, ap) { +struct ata_eh_context *ehc = &link->eh_context; -ata_link_for_each_dev (dev, link) - ehc->classes[dev->devno] =ATA_DEV_UNKNOWN ; +/* skip EH if possible. */ +if (ata_eh_skip_recovery (link)) + ehc->i.action =0 ; + +/* do we need to reset? */ +if (ehc->i.action &ATA_EH_RESET_MASK ) + reset =1 ; + +ata_link_for_each_dev (dev, link) + ehc->classes[dev->devno] =ATA_DEV_UNKNOWN ; + }/* reset */ -if (ehc->i.action &ATA_EH_RESET_MASK ) { +if (reset) {ata_eh_freeze_port (ap); - rc =ata_eh_reset (link,ata_link_nr_vacant (link), prereset, - softreset, hardreset, postreset); -if (rc) { -ata_link_printk (link,KERN_ERR , -"reset failed, giving up\n" ); - goto out; +ata_port_for_each_link (link, ap) { +struct ata_eh_context *ehc = &link->eh_context; + +if (!(ehc->i.action &ATA_EH_RESET_MASK )) +continue ; + + rc =ata_eh_reset (link,ata_link_nr_vacant (link), + prereset, softreset, hardreset, + postreset); +if (rc) { +ata_link_printk (link,KERN_ERR , +"reset failed, giving up\n" ); + goto out; + } }ata_eh_thaw_port (ap); } -/* revalidate existing devices and attach new ones */ - rc =ata_eh_revalidate_and_attach (link, &dev); -if (rc) - goto dev_fail; +/* the rest */ +ata_port_for_each_link (link, ap) { +struct ata_eh_context *ehc = &link->eh_context; -/* configure transfer mode if necessary */ -if (ehc->i.flags &ATA_EHI_SETMODE ) { - rc =ata_set_mode (link, &dev); +/* revalidate existing devices and attach new ones */ + rc =ata_eh_revalidate_and_attach (link, &dev);if (rc) goto dev_fail; - ehc->i.flags &= ~ATA_EHI_SETMODE ; - } - goto out; +/* configure transfer mode if necessary */ +if (ehc->i.flags &ATA_EHI_SETMODE ) { + rc =ata_set_mode (link, &dev); +if (rc) + goto dev_fail; + ehc->i.flags &= ~ATA_EHI_SETMODE ; + } + +/* this link is okay now */ + ehc->i.flags =0 ; +continue ; - dev_fail: -ata_eh_handle_dev_fail (dev, rc); + dev_fail: + nr_failed_devs++; +if (ata_eh_handle_dev_fail (dev, rc)) + nr_disabled_devs++; -if (ata_link_nr_enabled (link)) { -ata_link_printk (link,KERN_WARNING ,"failed to recover some " -"devices, retrying in 5 secs\n" ); -ssleep (5 ); - }else { -/* no device left, repeat fast */ -msleep (500 ); +if (ap->pflags &ATA_PFLAG_FROZEN ) +break ; } - goto retry; +if (nr_failed_devs) { +if (nr_failed_devs != nr_disabled_devs) { +ata_port_printk (ap,KERN_WARNING ,"failed to recover " +"some devices, retrying in 5 secs\n" ); +ssleep (5 ); + }else { +/* no device left to recover, repeat fast */ +msleep (500 ); + } - out: -if (rc) { -ata_link_for_each_dev (dev, link); -ata_dev_disable (dev); + goto retry; } + out: +if (rc && r_failed_link) + *r_failed_link = link; +DPRINTK ("EXIT, rc=%d\n" , rc);return rc; }
@@ -2277,9 +2355,19 @@ void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset, ata_reset_fn_t softreset, ata_reset_fn_t hardreset, ata_postreset_fn_t postreset) { - ata_eh_autopsy(&ap->link); -ata_eh_report (&ap->link); -ata_eh_recover (ap, prereset, softreset, hardreset, postreset); + struct ata_device *dev; +int rc; + +ata_eh_autopsy (ap); +ata_eh_report (ap); + + rc =ata_eh_recover (ap, prereset, softreset, hardreset, postreset, +NULL ); +if (rc) { +ata_link_for_each_dev (dev, &ap->link) +ata_dev_disable (dev); + } +ata_eh_finish (ap); }
Signature · 1 line
1.5.0.3
Re: [PATCH 14/16] libata-link: update EH to deal with PMP links
Quoted 13 lines · Tejun Heo
Update
ata_eh_autopsy(),ata_eh_report(),ata_eh_revalidate_and_attach()andata_eh_recover()to deal with PMP links.ata_eh_autopsy()andata_eh_report()updates are straightforward. They just repeat the same operation over all configured links. The only change toata_eh_revalidate_and_attach()is avoiding calling ->cable_select() on non-host ports.
ata_eh_recover()update is more complex as it first processes all resets and then performs the rest. This is necessary as thawing with some links in unknown state can be dangerous.ehi->actionis cleared on successful recovery of a link to avoid repeating recovery due to failures in other links.
Quoted 6 lines
ata_eh_recover()iterates over only PMP links if PMP is attached, and, on failure, the failing link is returned in @failed_link instead of disabling devices directly. These are to integrateata_eh_recover()into PMP EH later.Signed-off-by Tejun Heo <[email protected]>
ACK 11-14
PATCH 15/16 libata-link: update hotplug to handle PMP links
In reply to Tejun HeoUpdate hotplug to handle PMP links. When PMP is attached, the PMP number corresponds to I of SCSI C:H:I:L.
--- drivers/ata/libata-core.c | 7 ++- drivers/ata/libata-scsi.c | 123 ++++++++++++++++++++++++++++++--------------- 2 files changed, 87 insertions(+), 43 deletions(-)
drivers/ata/libata-core.c +5 -2
@@ -6529,6 +6529,7 @@ int ata_host_activate(struct ata_host *host, int irq,void ata_port_detach (struct ata_port *ap) {unsigned long flags; +struct ata_link *link;struct ata_device *dev;if (!ap->ops->error_handler)
@@ -6546,8 +6547,10 @@ void ata_port_detach(struct ata_port *ap)*/ spin_lock_irqsave (ap->lock, flags); -ata_link_for_each_dev (dev, &ap->link) -ata_dev_disable (dev); +ata_port_for_each_link (link, ap) { +ata_link_for_each_dev (dev, link) +ata_dev_disable (dev); + }spin_unlock_irqrestore (ap->lock, flags);
drivers/ata/libata-scsi.c +82 -41
197 lines not on this page · raw message
Signature · 1 line
1.5.0.3
Re: [PATCH 15/16] libata-link: update hotplug to handle PMP links
Quoted 2 lines · Tejun Heo
Update hotplug to handle PMP links. When PMP is attached, the PMP number corresponds to I of SCSI C:H:I:L.
That doesn't sound right. 'I' == ID == SCSI concept of a target. 'I' needs to be the end device, with 'L' (LUN) being normally zero, but sometimes otherwise -- in the case of multi-LUN ATAPI devices. Also, you have the order wrong, it's HCIL (host/channel/id/lun).
Since libata uses one SCSI host per port, HCIL translates to (port/link/id/lun) I should think.
Jeff
Re: [PATCH 15/16] libata-link: update hotplug to handle PMP links
Quoted 8 lines · Jeff Garzik
Quoted 2 lines · Tejun Heo
Update hotplug to handle PMP links. When PMP is attached, the PMP number corresponds to I of SCSI C:H:I:L.
That doesn't sound right. 'I' == ID == SCSI concept of a target. 'I' needs to be the end device, with 'L' (LUN) being normally zero, but sometimes otherwise -- in the case of multi-LUN ATAPI devices. Also, you have the order wrong, it's HCIL (host/channel/id/lun).
Yeah, that's from CHS. :-)
Quoted 2 lines
Since libata uses one SCSI host per port, HCIL translates to (port/link/id/lun) I should think.
Alright, will change.
Signature · 1 line
tejun
PATCH 16/16 libata-link: update Power Management to handle PMP links
In reply to Tejun HeoUpdate Power Management to consider PMP links.
--- drivers/ata/libata-core.c | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-)
drivers/ata/libata-core.c +5 -2
@@ -5838,6 +5838,7 @@ static int ata_host_request_pm(struct ata_host *host, pm_message_t mesg,for (i =0 ; i < host->n_ports; i++) {struct ata_port *ap = host->ports[i]; +struct ata_link *link;/* Previous resume operation might still be in * progress. Wait for PM_PENDING to clear.
@@ -5857,8 +5858,10 @@ static int ata_host_request_pm(struct ata_host *host, pm_message_t mesg, } ap->pflags |=ATA_PFLAG_PM_PENDING ; - ap->link.eh_info.action |= action; - ap->link.eh_info.flags |= ehi_flags; +__ata_port_for_each_link (link, ap) { + link->eh_info.action |= action; + link->eh_info.flags |= ehi_flags; + }ata_port_schedule_eh (ap);
Signature · 1 line
1.5.0.3
Re: [PATCH 16/16] libata-link: update Power Management to handle PMP links
Quoted 6 lines · Tejun Heo
Update Power Management to consider PMP links.
Signed-off-by Tejun Heo <[email protected]>--- drivers/ata/libata-core.c | 7 +++++-- 1 files changed, 5 insertions(+), 2 deletions(-)
ACK