#include <linux/libata.h>
#define DRV_NAME "sata_sil"
-#define DRV_VERSION "2.0"
+#define DRV_VERSION "2.2"
enum {
SIL_MMIO_BAR = 5,
#ifdef CONFIG_PM
static int sil_pci_device_resume(struct pci_dev *pdev);
#endif
-static void sil_dev_config(struct ata_port *ap, struct ata_device *dev);
+static void sil_dev_config(struct ata_device *dev);
static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg);
static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
-static void sil_post_set_mode (struct ata_port *ap);
+static int sil_set_mode (struct ata_port *ap, struct ata_device **r_failed);
static irqreturn_t sil_interrupt(int irq, void *dev_instance);
static void sil_freeze(struct ata_port *ap);
static void sil_thaw(struct ata_port *ap);
.slave_configure = ata_scsi_slave_config,
.slave_destroy = ata_scsi_slave_destroy,
.bios_param = ata_std_bios_param,
+#ifdef CONFIG_PM
.suspend = ata_scsi_device_suspend,
.resume = ata_scsi_device_resume,
+#endif
};
static const struct ata_port_operations sil_ops = {
.check_status = ata_check_status,
.exec_command = ata_exec_command,
.dev_select = ata_std_dev_select,
- .post_set_mode = sil_post_set_mode,
+ .set_mode = sil_set_mode,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
.bmdma_stop = ata_bmdma_stop,
return cache_line;
}
-static void sil_post_set_mode (struct ata_port *ap)
+/**
+ * sil_set_mode - wrap set_mode functions
+ * @ap: port 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)
{
struct ata_host *host = ap->host;
struct ata_device *dev;
void __iomem *addr = mmio_base + sil_port[ap->port_no].xfer_mode;
u32 tmp, dev_mode[2];
unsigned int i;
+ int rc;
+
+ rc = ata_do_set_mode(ap, r_failed);
+ if (rc)
+ return rc;
for (i = 0; i < 2; i++) {
dev = &ap->device[i];
tmp |= (dev_mode[1] << 4);
writel(tmp, addr);
readl(addr); /* flush */
+ return 0;
}
static inline void __iomem *sil_scr_addr(struct ata_port *ap, unsigned int sc_reg)
break;
}
- return 0;
+ return NULL;
}
static u32 sil_scr_read (struct ata_port *ap, unsigned int sc_reg)
goto freeze;
}
- if (unlikely(!qc || qc->tf.ctl & ATA_NIEN))
+ if (unlikely(!qc))
goto freeze;
+ if (unlikely(qc->tf.flags & ATA_TFLAG_POLLING)) {
+ /* this sometimes happens, just clear IRQ */
+ ata_chk_status(ap);
+ return;
+ }
+
/* Check whether we are expecting interrupt in this state */
switch (ap->hsm_task_state) {
case HSM_ST_FIRST:
/**
* sil_dev_config - Apply device/host-specific errata fixups
- * @ap: Port containing device to be examined
* @dev: Device to be examined
*
* After the IDENTIFY [PACKET] DEVICE step is complete, and a
* appreciated.
* - But then again UDMA5 is hardly anything to complain about
*/
-static void sil_dev_config(struct ata_port *ap, struct ata_device *dev)
+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;
unsigned int n, quirks = 0;
unsigned char model_num[ATA_ID_PROD_LEN + 1];