[PATCH] Re: AHCI oops

From: Jeff Garzik
Date: Tue Feb 22 2005 - 21:50:13 EST


Can you try this patch?

If it fixes the oops, I'll forward upstream ASAP.

Jeff



===== drivers/scsi/ahci.c 1.14 vs edited =====
--- 1.14/drivers/scsi/ahci.c 2005-02-13 19:58:01 -05:00
+++ edited/drivers/scsi/ahci.c 2005-02-22 21:46:25 -05:00
@@ -179,6 +179,7 @@
static void ahci_host_stop(struct ata_host_set *host_set);
static void ahci_qc_prep(struct ata_queued_cmd *qc);
static u8 ahci_check_status(struct ata_port *ap);
+static u8 ahci_check_err(struct ata_port *ap);
static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);

static Scsi_Host_Template ahci_sht = {
@@ -204,6 +205,8 @@
.port_disable = ata_port_disable,

.check_status = ahci_check_status,
+ .check_altstatus = ahci_check_status,
+ .check_err = ahci_check_err,
.dev_select = ata_noop_dev_select,

.phy_reset = ahci_phy_reset,
@@ -450,6 +453,13 @@
void *mmio = (void *) ap->ioaddr.cmd_addr;

return readl(mmio + PORT_TFDATA) & 0xFF;
+}
+
+static u8 ahci_check_err(struct ata_port *ap)
+{
+ void *mmio = (void *) ap->ioaddr.cmd_addr;
+
+ return (readl(mmio + PORT_TFDATA) >> 8) & 0xFF;
}

static void ahci_fill_sg(struct ata_queued_cmd *qc)
===== drivers/scsi/libata-core.c 1.120 vs edited =====
--- 1.120/drivers/scsi/libata-core.c 2005-02-22 21:19:40 -05:00
+++ edited/drivers/scsi/libata-core.c 2005-02-22 21:45:16 -05:00
@@ -377,7 +377,7 @@
}

/**
- * ata_check_status - Read device status reg & clear interrupt
+ * ata_check_status_pio - Read device status reg & clear interrupt
* @ap: port where the device is
*
* Reads ATA taskfile status register for currently-selected device
@@ -415,6 +415,27 @@
return ata_check_status_pio(ap);
}

+u8 ata_altstatus(struct ata_port *ap)
+{
+ if (ap->ops->check_altstatus)
+ return ap->ops->check_altstatus(ap);
+
+ if (ap->flags & ATA_FLAG_MMIO)
+ return readb((void __iomem *)ap->ioaddr.altstatus_addr);
+ return inb(ap->ioaddr.altstatus_addr);
+}
+
+u8 ata_chk_err(struct ata_port *ap)
+{
+ if (ap->ops->check_err)
+ return ap->ops->check_err(ap);
+
+ if (ap->flags & ATA_FLAG_MMIO) {
+ return readb((void __iomem *) ap->ioaddr.error_addr);
+ }
+ return inb(ap->ioaddr.error_addr);
+}
+
/**
* ata_tf_to_fis - Convert ATA taskfile to SATA FIS structure
* @tf: Taskfile to convert
@@ -1161,7 +1182,6 @@
printk(KERN_WARNING "ata%u: dev %u not supported, ignoring\n",
ap->id, device);
err_out:
- ata_irq_on(ap); /* re-enable interrupts */
dev->class++; /* converts ATA_DEV_xxx into ATA_DEV_xxx_UNSUP */
DPRINTK("EXIT, err\n");
}
@@ -1669,7 +1689,8 @@
ata_dev_try_classify(ap, 1);

/* re-enable interrupts */
- ata_irq_on(ap);
+ if (ap->ioaddr.ctl_addr) /* FIXME: hack. create a hook instead */
+ ata_irq_on(ap);

/* is double-select really necessary? */
if (ap->device[1].class != ATA_DEV_NONE)
@@ -3972,6 +3993,8 @@
EXPORT_SYMBOL_GPL(ata_tf_to_fis);
EXPORT_SYMBOL_GPL(ata_tf_from_fis);
EXPORT_SYMBOL_GPL(ata_check_status);
+EXPORT_SYMBOL_GPL(ata_altstatus);
+EXPORT_SYMBOL_GPL(ata_chk_err);
EXPORT_SYMBOL_GPL(ata_exec_command);
EXPORT_SYMBOL_GPL(ata_port_start);
EXPORT_SYMBOL_GPL(ata_port_stop);
===== include/linux/libata.h 1.64 vs edited =====
--- 1.64/include/linux/libata.h 2005-02-17 19:29:16 -05:00
+++ edited/include/linux/libata.h 2005-02-22 21:37:02 -05:00
@@ -334,6 +334,8 @@

void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf);
u8 (*check_status)(struct ata_port *ap);
+ u8 (*check_altstatus)(struct ata_port *ap);
+ u8 (*check_err)(struct ata_port *ap);
void (*dev_select)(struct ata_port *ap, unsigned int device);

void (*phy_reset) (struct ata_port *ap);
@@ -403,6 +405,8 @@
extern void ata_noop_dev_select (struct ata_port *ap, unsigned int device);
extern void ata_std_dev_select (struct ata_port *ap, unsigned int device);
extern u8 ata_check_status(struct ata_port *ap);
+extern u8 ata_altstatus(struct ata_port *ap);
+extern u8 ata_chk_err(struct ata_port *ap);
extern void ata_exec_command(struct ata_port *ap, struct ata_taskfile *tf);
extern int ata_port_start (struct ata_port *ap);
extern void ata_port_stop (struct ata_port *ap);
@@ -457,24 +461,9 @@
(dev->class == ATA_DEV_ATAPI));
}

-static inline u8 ata_chk_err(struct ata_port *ap)
-{
- if (ap->flags & ATA_FLAG_MMIO) {
- return readb((void __iomem *) ap->ioaddr.error_addr);
- }
- return inb(ap->ioaddr.error_addr);
-}
-
static inline u8 ata_chk_status(struct ata_port *ap)
{
return ap->ops->check_status(ap);
-}
-
-static inline u8 ata_altstatus(struct ata_port *ap)
-{
- if (ap->flags & ATA_FLAG_MMIO)
- return readb((void __iomem *)ap->ioaddr.altstatus_addr);
- return inb(ap->ioaddr.altstatus_addr);
}

static inline void ata_pause(struct ata_port *ap)