RE: [PATCH 2.6.20-stable] sata_vsc: fix 2.6.19 to .20 regression whilerefactoring vsc_sata_interrupt

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



 I put in this patch and I get:
00/00:00:00:00:00/e0 tag 0 cdb 0x0 data 4096 in
[ 1416.680306]          res 40/00:00:00:00:00/00:00:00:00:00/00 Emask
0x20 (host bus error)
[ 1416.723962] ATA: abnormal status 0xD0 on port 0xE100821C
[ 1416.746129] ATA: abnormal status 0xD0 on port 0xE100821C
[ 1416.768582] ATA: abnormal status 0xD0 on port 0xE100821C
[ 1416.790738] ATA: abnormal status 0xD0 on port 0xE100821C
[ 1416.812946] ATA: abnormal status 0xD0 on port 0xE100821C
[ 1446.831480] ata1.00: qc timeout (cmd 0xec)
[ 1446.839662] ata1.00: failed to IDENTIFY (I/O error, err_mask=0x4)
[ 1446.851797] ata1.00: revalidation failed (errno=-5)
[ 1446.861508] ata1: failed to recover some devices, retrying in 5 secs
[ 1459.187364] ata1: port is slow to respond, please be patient (Status
0xd0)
[ 1482.215332] ata1: port failed to respond (30 secs, Status 0xd0)
[ 1482.227146] ata1: soft resetting port
[ 1482.387350] ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300)
[ 1482.411264] ATA: abnormal status 0xD0 on port 0xE100821C
[ 1482.433434] ATA: abnormal status 0xD0 on port 0xE100821C
[ 1482.455604] ATA: abnormal status 0xD0 on port 0xE100821C
[ 1482.477759] ATA: abnormal status 0xD0 on port 0xE100821C
[ 1482.499966] ATA: abnormal status 0xD0 on port 0xE100821C
[ 1482.515381] ata1.00: revalidation failed (errno=-2)
[ 1482.525090] ata1: failed to recover some devices, retrying in 5 secs
[ 1487.539353] ata1: hard resetting port
[ 1487.863369] ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300)
[ 1487.891790] ata1.00: configured for UDMA/133
[ 1487.900364] ata1: EH complete
[ 1517.903401] ata1.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x0
[ 1517.916286] ata1.00: cmd c8/00:08:00:00:00/00:00:00:00:00/e0 tag 0
cdb 0x0 data 4096 in
[ 1517.916298]          res 40/00:00:00:00:00/00:00:00:00:00/00 Emask
0x20 (host bus error)
[ 1517.959964] ATA: abnormal status 0xD0 on port 0xE100821C
[ 1517.982140] ATA: abnormal status 0xD0 on port 0xE100821C
[ 1518.004311] ATA: abnormal status 0xD0 on port 0xE100821C
[ 1518.026467] ATA: abnormal status 0xD0 on port 0xE100821C
[ 1518.048676] ATA: abnormal status 0xD0 on port 0xE100821C
[ 1548.055367] ata1.00: qc timeout (cmd 0xec)
[ 1548.063547] ata1.00: failed to IDENTIFY (I/O error, err_mask=0x4)
[ 1548.075681] ata1.00: revalidation failed (errno=-5)
[ 1548.085390] ata1: failed to recover some devices, retrying in 5 secs
[ 1560.411363] ata1: port is slow to respond, please be patient (Status
0xd0)
[ 1583.439334] ata1: port failed to respond (30 secs, Status 0xd0)
[ 1583.451146] ata1: soft resetting port
[ 1583.611347] ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300)
[ 1583.635257] ATA: abnormal status 0xD0 on port 0xE100821C
[ 1583.657432] ATA: abnormal status 0xD0 on port 0xE100821C
[ 1583.679602] ATA: abnormal status 0xD0 on port 0xE100821C
[ 1583.701756] ATA: abnormal status 0xD0 on port 0xE100821C
[ 1583.723962] ATA: abnormal status 0xD0 on port 0xE100821C
[ 1583.755661] ata1.00: revalidation failed (errno=-2)
[ 1583.765373] ata1: failed to recover some devices, retrying in 5 secs
[ 1588.779357] ata1: hard resetting port
[ 1589.103368] ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300)
[ 1589.131792] ata1.00: configured for UDMA/133
[ 1589.140368] ata1: EH complete
[ 1619.143401] ata1.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x0
[ 1619.156286] ata1.00: cmd c8/00:08:00:00:00/00:00:00:00:00/e0 tag 0
cdb 0x0 data 4096 in
[ 1619.156298]          res 40/00:00:00:00:00/00:00:00:00:00/00 Emask
0x20 (host bus error)
[ 1619.199953] ATA: abnormal status 0xD0 on port 0xE100821C
[ 1619.222128] ATA: abnormal status 0xD0 on port 0xE100821C
[ 1619.244300] ATA: abnormal status 0xD0 on port 0xE100821C
[ 1619.266458] ATA: abnormal status 0xD0 on port 0xE100821C
[ 1619.288666] ATA: abnormal status 0xD0 on port 0xE100821C
[ 1649.307479] ata1.00: qc timeout (cmd 0xec)
[ 1649.315663] ata1.00: failed to IDENTIFY (I/O error, err_mask=0x4)
[ 1649.327796] ata1.00: revalidation failed (errno=-5)
[ 1649.337509] ata1: failed to recover some devices, retrying in 5 secs
[ 1661.663364] ata1: port is slow to respond, please be patient (Status
0xd0)
[ 1684.691331] ata1: port failed to respond (30 secs, Status 0xd0)
[ 1684.703143] ata1: soft resetting port
[ 1684.863349] ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300)
[ 1684.887263] ATA: abnormal status 0xD0 on port 0xE100821C
[ 1684.909433] ATA: abnormal status 0xD0 on port 0xE100821C
[ 1684.931604] ATA: abnormal status 0xD0 on port 0xE100821C
[ 1684.953759] ATA: abnormal status 0xD0 on port 0xE100821C
[ 1684.975966] ATA: abnormal status 0xD0 on port 0xE100821C
[ 1685.007380] ata1.00: revalidation failed (errno=-2)
[ 1685.017089] ata1: failed to recover some devices, retrying in 5 secs
[ 1690.031356] ata1: hard resetting port
[ 1690.355368] ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300)
[ 1690.383791] ata1.00: configured for UDMA/133
[ 1690.392371] sd 0:0:0:0: SCSI error: return code = 0x08000002
[ 1690.403642] sda: Current [descriptor]: sense key: Aborted Command
[ 1690.415762]     Additional sense: No additional sense information
[ 1690.427880] Descriptor sense data with sense descriptors (in hex):
[ 1690.440172]         72 0b 00 00 00 00 00 0c 00 0a 80 00 00 00 00 00
[ 1690.452808]         00 00 00 00
[ 1690.459216] end_request: I/O error, dev sda, sector 0
[ 1690.469277] Buffer I/O error on device sda, logical block 0
[ 1690.480431] ata1: EH complete
[ 1690.486364]  unknown partition table
[ 1690.502907] sd 0:0:0:0: Attached scsi disk sda
[ 1690.529977] sd 0:0:0:0: Attached scsi generic sg0 type 0

When I just put in this patch:
@@ -258,6 +258,10 @@
                                        /* Clear interrupt status */
                                        ata_chk_status(ap);
                                        handled++;
+                               } else if(qc->tf.command ==
ATA_CMD_ID_ATA) {
+                                       /* 31244 interrupts on polled
IDENTIFY
+commands */
+                                       ata_chk_status(ap);
                                }
                        }
                }

it worked fine on an intel system, and allowed me to fdisk/dd on a ppc
(but didn't
let the kernel read the partition table).  On ppc, it also cycled
through the udma modes with the small
patch...

marty


> -----Original Message-----
> From: Dan Williams [mailto:dan.j.williams@xxxxxxxxx] 
> Sent: Friday, July 06, 2007 12:14 PM
> To: stable@xxxxxxxxxx
> Cc: linux-ide@xxxxxxxxxxxxxxx; Leisner, Martin
> Subject: [PATCH 2.6.20-stable] sata_vsc: fix 2.6.19 to .20 
> regression whilerefactoring vsc_sata_interrupt
> 
> From: Dan Williams <dan.j.williams@xxxxxxxxx>
> 
> Separate sata_vsc interrupt handling into a normal (per-port) 
> path and an
> error path with the addition of vsc_port_intr and vsc_error_intr
> respectively.  The error path handles interrupt based
> hotplug events which requires the definition of vsc_freeze 
> and vsc_thaw.
> 
> Note: vsc_port_intr has a workaround for unexpected 
> interrupts that occur
> during polled commands.  This fixes a regression between 
> 2.6.19 and 2.6.20.
> Caused by 800b399669ad495ad4361d134df87401ae36f44f.
> 
> Changes in take2:
> * removed definition of invalid fis bit
> * let standard ata-error-handling handle the serror register
> * clear all unhandled interrupts
> * revert changes to vsc_intr_mask_update (vsc_thaw enables 
> all interrupts)
> * use unlikely() for the pci-abort and not-our-interrupt 
> cases in vsc_sata_interrupt
> 
> Changes in take3:
> * Unify the "add" + "hook-up" patches into this single patch
> 
> [htejun@xxxxxxxxx: clean up comments and suggestions]
> Cc: Jeremy Higdon <jeremy@xxxxxxx>
> Signed-off-by: Dan Williams <dan.j.williams@xxxxxxxxx>
> ---
> 
>  drivers/ata/sata_vsc.c |  123 
> +++++++++++++++++++++++++++++-------------------
>  1 files changed, 74 insertions(+), 49 deletions(-)
> 
> diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c
> index 0fa1b89..bcfca62 100644
> --- a/drivers/ata/sata_vsc.c
> +++ b/drivers/ata/sata_vsc.c
> @@ -96,11 +96,6 @@ enum {
>  			      VSC_SATA_INT_PHY_CHANGE),
>  };
>  
> -
> -#define is_vsc_sata_int_err(port_idx, int_status) \
> -	 (int_status & (VSC_SATA_INT_ERROR << (8 * port_idx)))
> -
> -
>  static u32 vsc_sata_scr_read (struct ata_port *ap, unsigned 
> int sc_reg)
>  {
>  	if (sc_reg > SCR_CONTROL)
> @@ -118,6 +113,28 @@ static void vsc_sata_scr_write (struct 
> ata_port *ap, unsigned int sc_reg,
>  }
>  
>  
> +static void vsc_freeze(struct ata_port *ap)
> +{
> +	void __iomem *mask_addr;
> +
> +	mask_addr = ap->host->mmio_base +
> +		VSC_SATA_INT_MASK_OFFSET + ap->port_no;
> +
> +	writeb(0, mask_addr);
> +}
> +
> +
> +static void vsc_thaw(struct ata_port *ap)
> +{
> +	void __iomem *mask_addr;
> +
> +	mask_addr = ap->host->mmio_base +
> +		VSC_SATA_INT_MASK_OFFSET + ap->port_no;
> +
> +	writeb(0xff, mask_addr);
> +}
> +
> +
>  static void vsc_intr_mask_update(struct ata_port *ap, u8 ctl)
>  {
>  	void __iomem *mask_addr;
> @@ -202,6 +219,36 @@ static void vsc_sata_tf_read(struct 
> ata_port *ap, struct ata_taskfile *tf)
>          }
>  }
>  
> +static inline void vsc_error_intr(u8 port_status, struct 
> ata_port *ap)
> +{
> +	if (port_status & (VSC_SATA_INT_PHY_CHANGE | 
> VSC_SATA_INT_ERROR_M))
> +		ata_port_freeze(ap);
> +	else
> +		ata_port_abort(ap);
> +}
> +
> +static void vsc_port_intr(u8 port_status, struct ata_port *ap)
> +{
> +	struct ata_queued_cmd *qc;
> +	int handled = 0;
> +
> +	if (unlikely(port_status & VSC_SATA_INT_ERROR)) {
> +		vsc_error_intr(port_status, ap);
> +		return;
> +	}
> +
> +	qc = ata_qc_from_tag(ap, ap->active_tag);
> +	if (qc && likely(!(qc->tf.flags & ATA_TFLAG_POLLING)))
> +		handled = ata_host_intr(ap, qc);
> +
> +	/* We received an interrupt during a polled command,
> +	 * or some other spurious condition.  Interrupt reporting
> +	 * with this hardware is fairly reliable so it is safe to
> +	 * simply clear the interrupt
> +	 */
> +	if (unlikely(!handled))
> +		ata_chk_status(ap);
> +}
>  
>  /*
>   * vsc_sata_interrupt
> @@ -213,58 +260,36 @@ static irqreturn_t vsc_sata_interrupt 
> (int irq, void *dev_instance)
>  	struct ata_host *host = dev_instance;
>  	unsigned int i;
>  	unsigned int handled = 0;
> -	u32 int_status;
> -
> -	spin_lock(&host->lock);
> +	u32 status;
>  
> -	int_status = readl(host->mmio_base + VSC_SATA_INT_STAT_OFFSET);
> +	status = readl(host->mmio_base + VSC_SATA_INT_STAT_OFFSET);
>  
> -	for (i = 0; i < host->n_ports; i++) {
> -		if (int_status & ((u32) 0xFF << (8 * i))) {
> -			struct ata_port *ap;
> +	if (unlikely(status == 0xffffffff || status == 0)) {
> +		if (status)
> +			dev_printk(KERN_ERR, host->dev,
> +				": IRQ status == 0xffffffff, "
> +				"PCI fault or device removal?\n");
> +		goto out;
> +	}
>  
> -			ap = host->ports[i];
> +	spin_lock(&host->lock);
>  
> -			if (is_vsc_sata_int_err(i, int_status)) {
> -				u32 err_status;
> -				printk(KERN_DEBUG "%s: ignoring 
> interrupt(s)\n", __FUNCTION__);
> -				err_status = ap ? 
> vsc_sata_scr_read(ap, SCR_ERROR) : 0;
> -				vsc_sata_scr_write(ap, 
> SCR_ERROR, err_status);
> -				handled++;
> -			}
> +	for (i = 0; i < host->n_ports; i++) {
> +		u8 port_status = (status >> (8 * i)) & 0xff;
> +		if (port_status) {
> +			struct ata_port *ap = host->ports[i];
>  
>  			if (ap && !(ap->flags & ATA_FLAG_DISABLED)) {
> -				struct ata_queued_cmd *qc;
> -
> -				qc = ata_qc_from_tag(ap, 
> ap->active_tag);
> -				if (qc && (!(qc->tf.flags & 
> ATA_TFLAG_POLLING)))
> -					handled += 
> ata_host_intr(ap, qc);
> -				else if (is_vsc_sata_int_err(i, 
> int_status)) {
> -					/*
> -					 * On some chips (i.e. 
> Intel 31244), an error
> -					 * interrupt will sneak 
> in at initialization
> -					 * time (phy state 
> changes).  Clearing the SCR
> -					 * error register is 
> not required, but it prevents
> -					 * the phy state change 
> interrupts from recurring
> -					 * later.
> -					 */
> -					u32 err_status;
> -					err_status = 
> vsc_sata_scr_read(ap, SCR_ERROR);
> -					printk(KERN_DEBUG "%s: 
> clearing interrupt, "
> -					       "status %x; sata 
> err status %x\n",
> -					       __FUNCTION__,
> -					       int_status, err_status);
> -					vsc_sata_scr_write(ap, 
> SCR_ERROR, err_status);
> -					/* Clear interrupt status */
> -					ata_chk_status(ap);
> -					handled++;
> -				}
> -			}
> +				vsc_port_intr(port_status, ap);
> +				handled++;
> +			} else
> +				dev_printk(KERN_ERR, host->dev,
> +					": interrupt from 
> disabled port %d\n", i);
>  		}
>  	}
>  
>  	spin_unlock(&host->lock);
> -
> +out:
>  	return IRQ_RETVAL(handled);
>  }
>  
> @@ -302,8 +327,8 @@ static const struct ata_port_operations 
> vsc_sata_ops = {
>  	.qc_prep		= ata_qc_prep,
>  	.qc_issue		= ata_qc_issue_prot,
>  	.data_xfer		= ata_mmio_data_xfer,
> -	.freeze			= ata_bmdma_freeze,
> -	.thaw			= ata_bmdma_thaw,
> +	.freeze			= vsc_freeze,
> +	.thaw			= vsc_thaw,
>  	.error_handler		= ata_bmdma_error_handler,
>  	.post_internal_cmd	= ata_bmdma_post_internal_cmd,
>  	.irq_handler		= vsc_sata_interrupt,
> 
-
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Filesystems]     [Linux SCSI]     [Linux RAID]     [Git]     [Kernel Newbies]     [Linux Newbie]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Samba]     [Device Mapper]

  Powered by Linux