#include <linux/libata.h>
#define DRV_NAME "sata_nv"
-#define DRV_VERSION "0.9"
+#define DRV_VERSION "2.0"
enum {
NV_PORTS = 2,
NV_INT_PORT_SHIFT = 4, /* each port occupies 4 bits */
NV_INT_ALL = 0x0f,
- NV_INT_MASK = NV_INT_DEV,
+ NV_INT_MASK = NV_INT_DEV |
+ NV_INT_ADDED | NV_INT_REMOVED,
/* INT_CONFIG */
NV_INT_CONFIG = 0x12,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
{ PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
+ { PCI_VENDOR_ID_NVIDIA, 0x045c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
+ { PCI_VENDOR_ID_NVIDIA, 0x045d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
+ { PCI_VENDOR_ID_NVIDIA, 0x045e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
+ { PCI_VENDOR_ID_NVIDIA, 0x045f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, GENERIC },
{ PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC },
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
int handled;
+ /* freeze if hotplugged */
+ if (unlikely(irq_stat & (NV_INT_ADDED | NV_INT_REMOVED))) {
+ ata_port_freeze(ap);
+ return 1;
+ }
+
/* bail out if not our interrupt */
if (!(irq_stat & NV_INT_DEV))
return 0;
struct pt_regs *regs)
{
struct ata_host_set *host_set = dev_instance;
- unsigned long flags;
u8 irq_stat;
irqreturn_t ret;
- spin_lock_irqsave(&host_set->lock, flags);
+ spin_lock(&host_set->lock);
irq_stat = inb(host_set->ports[0]->ioaddr.scr_addr + NV_INT_STATUS);
ret = nv_do_interrupt(host_set, irq_stat);
- spin_unlock_irqrestore(&host_set->lock, flags);
+ spin_unlock(&host_set->lock);
return ret;
}
struct pt_regs *regs)
{
struct ata_host_set *host_set = dev_instance;
- unsigned long flags;
u8 irq_stat;
irqreturn_t ret;
- spin_lock_irqsave(&host_set->lock, flags);
+ spin_lock(&host_set->lock);
irq_stat = readb(host_set->mmio_base + NV_INT_STATUS_CK804);
ret = nv_do_interrupt(host_set, irq_stat);
- spin_unlock_irqrestore(&host_set->lock, flags);
+ spin_unlock(&host_set->lock);
return ret;
}