Commit 0202b160 authored by Jeff Garzik's avatar Jeff Garzik

Merge pobox.com:/garz/repo/netdev-2.6/r8169

into pobox.com:/garz/repo/net-drivers-2.6
parents 3cbae07b f5f23ec8
......@@ -107,8 +107,11 @@ pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
ptepage->mapping = (void *) mm;
ptepage->index = address & PMD_MASK;
}
} else
} else {
pte = (pte_t *)early_get_page();
if (pte)
clear_page(pte);
}
return pte;
}
......
......@@ -62,7 +62,7 @@ void flush_hash_one_pte(pte_t *ptep)
ptepage = virt_to_page(ptep);
mm = (struct mm_struct *) ptepage->mapping;
ptephys = __pa(ptep) & PAGE_MASK;
addr = ptepage->index + (((unsigned long)ptep & ~PAGE_MASK) << 9);
addr = ptepage->index + (((unsigned long)ptep & ~PAGE_MASK) << 10);
flush_hash_pages(mm->context, addr, ptephys, 1);
}
......
......@@ -628,11 +628,13 @@ int xmon_fault_handler(struct pt_regs *regs)
(data address breakpoint register) directly. */
static void set_controlled_dabr(unsigned long val)
{
#ifdef CONFIG_PPC_PSERIES
if (systemcfg->platform == PLATFORM_PSERIES_LPAR) {
int rc = plpar_hcall_norets(H_SET_DABR, val);
if (rc != H_Success)
xmon_printf("Warning: setting DABR failed (%d)\n", rc);
} else
#endif
set_dabr(val);
}
......
......@@ -34,7 +34,7 @@ struct alps_model_info {
unsigned char signature[3];
unsigned char model;
} alps_model_data[] = {
{ { 0x33, 0x02, 0x0a }, ALPS_MODEL_GLIDEPOINT },
/* { { 0x33, 0x02, 0x0a }, ALPS_MODEL_GLIDEPOINT }, */
{ { 0x53, 0x02, 0x0a }, ALPS_MODEL_GLIDEPOINT },
{ { 0x53, 0x02, 0x14 }, ALPS_MODEL_GLIDEPOINT },
{ { 0x63, 0x02, 0x0a }, ALPS_MODEL_GLIDEPOINT },
......@@ -42,8 +42,8 @@ struct alps_model_info {
{ { 0x73, 0x02, 0x0a }, ALPS_MODEL_GLIDEPOINT },
{ { 0x73, 0x02, 0x14 }, ALPS_MODEL_GLIDEPOINT },
{ { 0x63, 0x02, 0x28 }, ALPS_MODEL_GLIDEPOINT },
{ { 0x63, 0x02, 0x3c }, ALPS_MODEL_GLIDEPOINT },
{ { 0x63, 0x02, 0x50 }, ALPS_MODEL_GLIDEPOINT },
/* { { 0x63, 0x02, 0x3c }, ALPS_MODEL_GLIDEPOINT }, */
/* { { 0x63, 0x02, 0x50 }, ALPS_MODEL_GLIDEPOINT }, */
{ { 0x63, 0x02, 0x64 }, ALPS_MODEL_GLIDEPOINT },
{ { 0x20, 0x02, 0x0e }, ALPS_MODEL_DUALPOINT },
{ { 0x22, 0x02, 0x0a }, ALPS_MODEL_DUALPOINT },
......
......@@ -253,9 +253,9 @@ static struct region *__rh_alloc(struct region_hash *rh, region_t region)
else {
__rh_insert(rh, nreg);
if (nreg->state == RH_CLEAN) {
spin_lock_irq(&rh->region_lock);
spin_lock(&rh->region_lock);
list_add(&nreg->list, &rh->clean_regions);
spin_unlock_irq(&rh->region_lock);
spin_unlock(&rh->region_lock);
}
reg = nreg;
}
......
......@@ -457,6 +457,14 @@ config SCSI_SATA_PROMISE
If unsure, say N.
config SCSI_SATA_QSTOR
tristate "Pacific Digital SATA QStor support"
depends on SCSI_SATA && PCI
help
This option enables support for Pacific Digital Serial ATA QStor.
If unsure, say N.
config SCSI_SATA_SX4
tristate "Promise SATA SX4 support"
depends on SCSI_SATA && PCI && EXPERIMENTAL
......
......@@ -125,6 +125,7 @@ obj-$(CONFIG_SCSI_SATA_AHCI) += libata.o ahci.o
obj-$(CONFIG_SCSI_SATA_SVW) += libata.o sata_svw.o
obj-$(CONFIG_SCSI_ATA_PIIX) += libata.o ata_piix.o
obj-$(CONFIG_SCSI_SATA_PROMISE) += libata.o sata_promise.o
obj-$(CONFIG_SCSI_SATA_QSTOR) += libata.o sata_qstor.o
obj-$(CONFIG_SCSI_SATA_SIL) += libata.o sata_sil.o
obj-$(CONFIG_SCSI_SATA_VIA) += libata.o sata_via.o
obj-$(CONFIG_SCSI_SATA_VITESSE) += libata.o sata_vsc.o
......
......@@ -179,6 +179,7 @@ static void ahci_port_stop(struct ata_port *ap);
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 @@ static struct ata_port_operations ahci_ops = {
.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,
......@@ -452,6 +455,13 @@ static u8 ahci_check_status(struct ata_port *ap)
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)
{
struct ahci_port_priv *pp = qc->ap->private_data;
......@@ -940,6 +950,7 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
unsigned long base;
void *mmio_base;
unsigned int board_idx = (unsigned int) ent->driver_data;
int pci_dev_busy = 0;
int rc;
VPRINTK("ENTER\n");
......@@ -952,8 +963,10 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
return rc;
rc = pci_request_regions(pdev, DRV_NAME);
if (rc)
if (rc) {
pci_dev_busy = 1;
goto err_out;
}
pci_enable_intx(pdev);
......@@ -1015,7 +1028,8 @@ static int ahci_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
err_out_regions:
pci_release_regions(pdev);
err_out:
pci_disable_device(pdev);
if (!pci_dev_busy)
pci_disable_device(pdev);
return rc;
}
......
......@@ -138,6 +138,8 @@ static struct ata_port_operations piix_pata_ops = {
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
.bmdma_stop = ata_bmdma_stop,
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
......@@ -163,6 +165,8 @@ static struct ata_port_operations piix_sata_ops = {
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
.bmdma_stop = ata_bmdma_stop,
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
......
......@@ -377,7 +377,7 @@ void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
}
/**
* 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 @@ u8 ata_check_status(struct ata_port *ap)
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 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device)
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 @@ void ata_bus_reset(struct ata_port *ap)
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)
......@@ -2601,10 +2622,10 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc)
case ATA_PROT_DMA:
case ATA_PROT_ATAPI_DMA:
host_stat = ata_bmdma_status(ap);
host_stat = ap->ops->bmdma_status(ap);
/* before we do anything else, clear DMA-Start bit */
ata_bmdma_stop(ap);
ap->ops->bmdma_stop(ap);
/* fall through */
......@@ -2613,7 +2634,7 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc)
drv_stat = ata_chk_status(ap);
/* ack bmdma irq events */
ata_bmdma_ack_irq(ap);
ap->ops->irq_clear(ap);
printk(KERN_ERR "ata%u: command 0x%x timeout, stat 0x%x host_stat 0x%x\n",
ap->id, qc->tf.command, drv_stat, host_stat);
......@@ -2751,6 +2772,24 @@ static void __ata_qc_complete(struct ata_queued_cmd *qc)
clear_bit(tag, &ap->qactive);
}
/**
* ata_qc_free - free unused ata_queued_cmd
* @qc: Command to complete
*
* Designed to free unused ata_queued_cmd object
* in case something prevents using it.
*
* LOCKING:
*
*/
void ata_qc_free(struct ata_queued_cmd *qc)
{
assert(qc != NULL); /* ata_qc_from_tag _might_ return NULL */
assert(qc->waiting == NULL); /* nothing should be waiting */
__ata_qc_complete(qc);
}
/**
* ata_qc_complete - Complete an active ATA command
* @qc: Command to complete
......@@ -3042,7 +3081,43 @@ void ata_bmdma_setup(struct ata_queued_cmd *qc)
void ata_bmdma_irq_clear(struct ata_port *ap)
{
ata_bmdma_ack_irq(ap);
if (ap->flags & ATA_FLAG_MMIO) {
void __iomem *mmio = ((void __iomem *) ap->ioaddr.bmdma_addr) + ATA_DMA_STATUS;
writeb(readb(mmio), mmio);
} else {
unsigned long addr = ap->ioaddr.bmdma_addr + ATA_DMA_STATUS;
outb(inb(addr), addr);
}
}
u8 ata_bmdma_status(struct ata_port *ap)
{
u8 host_stat;
if (ap->flags & ATA_FLAG_MMIO) {
void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
host_stat = readb(mmio + ATA_DMA_STATUS);
} else
host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
return host_stat;
}
void ata_bmdma_stop(struct ata_port *ap)
{
if (ap->flags & ATA_FLAG_MMIO) {
void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
/* clear start/stop bit */
writeb(readb(mmio + ATA_DMA_CMD) & ~ATA_DMA_START,
mmio + ATA_DMA_CMD);
} else {
/* clear start/stop bit */
outb(inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD) & ~ATA_DMA_START,
ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
}
/* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
ata_altstatus(ap); /* dummy read */
}
/**
......@@ -3072,7 +3147,7 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
case ATA_PROT_ATAPI_DMA:
case ATA_PROT_ATAPI:
/* check status of DMA engine */
host_stat = ata_bmdma_status(ap);
host_stat = ap->ops->bmdma_status(ap);
VPRINTK("ata%u: host_stat 0x%X\n", ap->id, host_stat);
/* if it's not our irq... */
......@@ -3080,7 +3155,7 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
goto idle_irq;
/* before we do anything else, clear DMA-Start bit */
ata_bmdma_stop(ap);
ap->ops->bmdma_stop(ap);
/* fall through */
......@@ -3099,7 +3174,7 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
ap->id, qc->tf.protocol, status);
/* ack bmdma irq events */
ata_bmdma_ack_irq(ap);
ap->ops->irq_clear(ap);
/* complete taskfile transaction */
ata_qc_complete(qc, status);
......@@ -3656,6 +3731,7 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
struct ata_port_info *port[2];
u8 tmp8, mask;
unsigned int legacy_mode = 0;
int disable_dev_on_err = 1;
int rc;
DPRINTK("ENTER\n");
......@@ -3686,8 +3762,10 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
return rc;
rc = pci_request_regions(pdev, DRV_NAME);
if (rc)
if (rc) {
disable_dev_on_err = 0;
goto err_out;
}
if (legacy_mode) {
if (!request_region(0x1f0, 8, "libata")) {
......@@ -3697,8 +3775,10 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
conflict = ____request_resource(&ioport_resource, &res);
if (!strcmp(conflict->name, "libata"))
legacy_mode |= (1 << 0);
else
else {
disable_dev_on_err = 0;
printk(KERN_WARNING "ata: 0x1f0 IDE port busy\n");
}
} else
legacy_mode |= (1 << 0);
......@@ -3709,8 +3789,10 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
conflict = ____request_resource(&ioport_resource, &res);
if (!strcmp(conflict->name, "libata"))
legacy_mode |= (1 << 1);
else
else {
disable_dev_on_err = 0;
printk(KERN_WARNING "ata: 0x170 IDE port busy\n");
}
} else
legacy_mode |= (1 << 1);
}
......@@ -3760,7 +3842,8 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
release_region(0x170, 8);
pci_release_regions(pdev);
err_out:
pci_disable_device(pdev);
if (disable_dev_on_err)
pci_disable_device(pdev);
return rc;
}
......@@ -3910,6 +3993,8 @@ EXPORT_SYMBOL_GPL(ata_std_dev_select);
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);
......@@ -3918,6 +4003,8 @@ EXPORT_SYMBOL_GPL(ata_qc_prep);
EXPORT_SYMBOL_GPL(ata_bmdma_setup);
EXPORT_SYMBOL_GPL(ata_bmdma_start);
EXPORT_SYMBOL_GPL(ata_bmdma_irq_clear);
EXPORT_SYMBOL_GPL(ata_bmdma_status);
EXPORT_SYMBOL_GPL(ata_bmdma_stop);
EXPORT_SYMBOL_GPL(ata_port_probe);
EXPORT_SYMBOL_GPL(sata_phy_reset);
EXPORT_SYMBOL_GPL(__sata_phy_reset);
......
......@@ -701,6 +701,7 @@ static void ata_scsi_translate(struct ata_port *ap, struct ata_device *dev,
return;
err_out:
ata_qc_free(qc);
ata_bad_cdb(cmd, done);
DPRINTK("EXIT - badcmd\n");
}
......
......@@ -37,6 +37,7 @@ struct ata_scsi_args {
/* libata-core.c */
extern struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
struct ata_device *dev);
extern void ata_qc_free(struct ata_queued_cmd *qc);
extern int ata_qc_issue(struct ata_queued_cmd *qc);
extern int ata_check_atapi_dma(struct ata_queued_cmd *qc);
extern void ata_dev_select(struct ata_port *ap, unsigned int device,
......
......@@ -217,6 +217,8 @@ static struct ata_port_operations nv_ops = {
.phy_reset = sata_phy_reset,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
.bmdma_stop = ata_bmdma_stop,
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
.eng_timeout = ata_eng_timeout,
......@@ -332,6 +334,7 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
struct nv_host *host;
struct ata_port_info *ppi;
struct ata_probe_ent *probe_ent;
int pci_dev_busy = 0;
int rc;
u32 bar;
......@@ -350,8 +353,10 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out;
rc = pci_request_regions(pdev, DRV_NAME);
if (rc)
if (rc) {
pci_dev_busy = 1;
goto err_out_disable;
}
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
......@@ -427,7 +432,8 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
err_out_regions:
pci_release_regions(pdev);
err_out_disable:
pci_disable_device(pdev);
if (!pci_dev_busy)
pci_disable_device(pdev);
err_out:
return rc;
}
......
......@@ -556,6 +556,7 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
unsigned long base;
void *mmio_base;
unsigned int board_idx = (unsigned int) ent->driver_data;
int pci_dev_busy = 0;
int rc;
if (!printed_version++)
......@@ -570,8 +571,10 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
return rc;
rc = pci_request_regions(pdev, DRV_NAME);
if (rc)
if (rc) {
pci_dev_busy = 1;
goto err_out;
}
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
......@@ -650,7 +653,8 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
err_out_regions:
pci_release_regions(pdev);
err_out:
pci_disable_device(pdev);
if (!pci_dev_busy)
pci_disable_device(pdev);
return rc;
}
......
This diff is collapsed.
......@@ -139,6 +139,8 @@ static struct ata_port_operations sil_ops = {
.post_set_mode = sil_post_set_mode,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
.bmdma_stop = ata_bmdma_stop,
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
.eng_timeout = ata_eng_timeout,
......@@ -336,6 +338,7 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
void *mmio_base;
int rc;
unsigned int i;
int pci_dev_busy = 0;
u32 tmp, irq_mask;
if (!printed_version++)
......@@ -350,8 +353,10 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
return rc;
rc = pci_request_regions(pdev, DRV_NAME);
if (rc)
if (rc) {
pci_dev_busy = 1;
goto err_out;
}
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
......@@ -438,7 +443,8 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
err_out_regions:
pci_release_regions(pdev);
err_out:
pci_disable_device(pdev);
if (!pci_dev_busy)
pci_disable_device(pdev);
return rc;
}
......
......@@ -102,6 +102,8 @@ static struct ata_port_operations sis_ops = {
.phy_reset = sata_phy_reset,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
.bmdma_stop = ata_bmdma_stop,
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
.eng_timeout = ata_eng_timeout,
......@@ -200,14 +202,17 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
int rc;
u32 genctl;
struct ata_port_info *ppi;
int pci_dev_busy = 0;
rc = pci_enable_device(pdev);
if (rc)
return rc;
rc = pci_request_regions(pdev, DRV_NAME);
if (rc)
if (rc) {
pci_dev_busy = 1;
goto err_out;
}
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
......@@ -259,7 +264,8 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
pci_release_regions(pdev);
err_out:
pci_disable_device(pdev);
if (!pci_dev_busy)
pci_disable_device(pdev);
return rc;
}
......
......@@ -301,6 +301,8 @@ static struct ata_port_operations k2_sata_ops = {
.phy_reset = sata_phy_reset,
.bmdma_setup = k2_bmdma_setup_mmio,
.bmdma_start = k2_bmdma_start_mmio,
.bmdma_stop = ata_bmdma_stop,
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
.eng_timeout = ata_eng_timeout,
......@@ -338,6 +340,7 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
struct ata_probe_ent *probe_ent = NULL;
unsigned long base;
void *mmio_base;
int pci_dev_busy = 0;
int rc;
if (!printed_version++)
......@@ -359,8 +362,10 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
/* Request PCI regions */
rc = pci_request_regions(pdev, DRV_NAME);
if (rc)
if (rc) {
pci_dev_busy = 1;
goto err_out;
}
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
......@@ -433,7 +438,8 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
err_out_regions:
pci_release_regions(pdev);
err_out:
pci_disable_device(pdev);
if (!pci_dev_busy)
pci_disable_device(pdev);
return rc;
}
......
......@@ -1366,6 +1366,7 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
void *mmio_base, *dimm_mmio = NULL;
struct pdc_host_priv *hpriv = NULL;
unsigned int board_idx = (unsigned int) ent->driver_data;
int pci_dev_busy = 0;
int rc;
if (!printed_version++)
......@@ -1380,8 +1381,10 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
return rc;
rc = pci_request_regions(pdev, DRV_NAME);
if (rc)
if (rc) {
pci_dev_busy = 1;
goto err_out;
}
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
......@@ -1471,7 +1474,8 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
err_out_regions:
pci_release_regions(pdev);
err_out:
pci_disable_device(pdev);
if (!pci_dev_busy)
pci_disable_device(pdev);
return rc;
}
......
......@@ -97,6 +97,8 @@ static struct ata_port_operations uli_ops = {
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
.bmdma_stop = ata_bmdma_stop,
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
......@@ -185,14 +187,17 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
struct ata_port_info *ppi;
int rc;
unsigned int board_idx = (unsigned int) ent->driver_data;
int pci_dev_busy = 0;
rc = pci_enable_device(pdev);
if (rc)
return rc;
rc = pci_request_regions(pdev, DRV_NAME);
if (rc)
if (rc) {
pci_dev_busy = 1;
goto err_out;
}
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
......@@ -260,7 +265,8 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
pci_release_regions(pdev);
err_out:
pci_disable_device(pdev);
if (!pci_dev_busy)
pci_disable_device(pdev);
return rc;
}
......
......@@ -24,6 +24,11 @@
If you do not delete the provisions above, a recipient may use your
version of this file under either the OSL or the GPL.
----------------------------------------------------------------------
To-do list:
* VT6421 PATA support
*/
#include <linux/kernel.h>
......@@ -38,11 +43,14 @@
#include <asm/io.h>
#define DRV_NAME "sata_via"
#define DRV_VERSION "1.0"
#define DRV_VERSION "1.1"
enum {
via_sata = 0,
enum board_ids_enum {
vt6420,
vt6421,
};
enum {
SATA_CHAN_ENAB = 0x40, /* SATA channel enable */
SATA_INT_GATE = 0x41, /* SATA interrupt gating */
SATA_NATIVE_MODE = 0x42, /* Native mode enable */
......@@ -50,10 +58,8 @@ enum {
PORT0 = (1 << 1),
PORT1 = (1 << 0),
ENAB_ALL = PORT0 | PORT1,
INT_GATE_ALL = PORT0 | PORT1,
ALL_PORTS = PORT0 | PORT1,
N_PORTS = 2,
NATIVE_MODE_ALL = (1 << 7) | (1 << 6) | (1 << 5) | (1 << 4),
......@@ -66,7 +72,8 @@ static u32 svia_scr_read (struct ata_port *ap, unsigned int sc_reg);
static void svia_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
static struct pci_device_id svia_pci_tbl[] = {
{ 0x1106, 0x3149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, via_sata },
{ 0x1106, 0x3149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6420 },
{ 0x1106, 0x3249, PCI_ANY_ID, PCI_ANY_ID, 0, 0, vt6421 },
{ } /* terminate list */
};
......@@ -110,6 +117,9 @@ static struct ata_port_operations svia_sata_ops = {
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
.bmdma_stop = ata_bmdma_stop,
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
......@@ -158,18 +168,132 @@ static const unsigned int svia_bar_sizes[] = {
8, 4, 8, 4, 16, 256
};
static const unsigned int vt6421_bar_sizes[] = {
16, 16, 16, 16, 32, 128
};
static unsigned long svia_scr_addr(unsigned long addr, unsigned int port)
{
return addr + (port * 128);
}
static unsigned long vt6421_scr_addr(unsigned long addr, unsigned int port)
{
return addr + (port * 64);
}
static void vt6421_init_addrs(struct ata_probe_ent *probe_ent,
struct pci_dev *pdev,
unsigned int port)
{
unsigned long reg_addr = pci_resource_start(pdev, port);
unsigned long bmdma_addr = pci_resource_start(pdev, 4) + (port * 8);
unsigned long scr_addr;
probe_ent->port[port].cmd_addr = reg_addr;
probe_ent->port[port].altstatus_addr =
probe_ent->port[port].ctl_addr = (reg_addr + 8) | ATA_PCI_CTL_OFS;
probe_ent->port[port].bmdma_addr = bmdma_addr;
scr_addr = vt6421_scr_addr(pci_resource_start(pdev, 5), port);
probe_ent->port[port].scr_addr = scr_addr;
ata_std_ports(&probe_ent->port[port]);
}
static struct ata_probe_ent *vt6420_init_probe_ent(struct pci_dev *pdev)
{
struct ata_probe_ent *probe_ent;
struct ata_port_info *ppi = &svia_port_info;
probe_ent = ata_pci_init_native_mode(pdev, &ppi);
if (!probe_ent)
return NULL;
probe_ent->port[0].scr_addr =
svia_scr_addr(pci_resource_start(pdev, 5), 0);
probe_ent->port[1].scr_addr =
svia_scr_addr(pci_resource_start(pdev, 5), 1);
return probe_ent;
}
static struct ata_probe_ent *vt6421_init_probe_ent(struct pci_dev *pdev)
{
struct ata_probe_ent *probe_ent;
unsigned int i;
probe_ent = kmalloc(sizeof(*probe_ent), GFP_KERNEL);
if (!probe_ent)
return NULL;
memset(probe_ent, 0, sizeof(*probe_ent));
probe_ent->dev = pci_dev_to_dev(pdev);
INIT_LIST_HEAD(&probe_ent->node);
probe_ent->sht = &svia_sht;
probe_ent->host_flags = ATA_FLAG_SATA | ATA_FLAG_SATA_RESET |
ATA_FLAG_NO_LEGACY;
probe_ent->port_ops = &svia_sata_ops;
probe_ent->n_ports = N_PORTS;
probe_ent->irq = pdev->irq;
probe_ent->irq_flags = SA_SHIRQ;
probe_ent->pio_mask = 0x1f;
probe_ent->mwdma_mask = 0x07;
probe_ent->udma_mask = 0x7f;
for (i = 0; i < N_PORTS; i++)
vt6421_init_addrs(probe_ent, pdev, i);
return probe_ent;
}
static void svia_configure(struct pci_dev *pdev)
{
u8 tmp8;
pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &tmp8);
printk(KERN_INFO DRV_NAME "(%s): routed to hard irq line %d\n",
pci_name(pdev),
(int) (tmp8 & 0xf0) == 0xf0 ? 0 : tmp8 & 0x0f);
/* make sure SATA channels are enabled */
pci_read_config_byte(pdev, SATA_CHAN_ENAB, &tmp8);
if ((tmp8 & ALL_PORTS) != ALL_PORTS) {
printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channels (0x%x)\n",
pci_name(pdev), (int) tmp8);
tmp8 |= ALL_PORTS;
pci_write_config_byte(pdev, SATA_CHAN_ENAB, tmp8);
}
/* make sure interrupts for each channel sent to us */
pci_read_config_byte(pdev, SATA_INT_GATE, &tmp8);
if ((tmp8 & ALL_PORTS) != ALL_PORTS) {
printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channel interrupts (0x%x)\n",
pci_name(pdev), (int) tmp8);
tmp8 |= ALL_PORTS;
pci_write_config_byte(pdev, SATA_INT_GATE, tmp8);
}
/* make sure native mode is enabled */
pci_read_config_byte(pdev, SATA_NATIVE_MODE, &tmp8);
if ((tmp8 & NATIVE_MODE_ALL) != NATIVE_MODE_ALL) {
printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channel native mode (0x%x)\n",
pci_name(pdev), (int) tmp8);
tmp8 |= NATIVE_MODE_ALL;
pci_write_config_byte(pdev, SATA_NATIVE_MODE, tmp8);
}
}
static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
unsigned int i;
int rc;
struct ata_port_info *ppi;
struct ata_probe_ent *probe_ent;
int board_id = (int) ent->driver_data;
const int *bar_sizes;
int pci_dev_busy = 0;
u8 tmp8;
if (!printed_version++)
......@@ -180,20 +304,28 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
return rc;
rc = pci_request_regions(pdev, DRV_NAME);
if (rc)
if (rc) {
pci_dev_busy = 1;
goto err_out;
}
pci_read_config_byte(pdev, SATA_PATA_SHARING, &tmp8);
if (tmp8 & SATA_2DEV) {
printk(KERN_ERR DRV_NAME "(%s): SATA master/slave not supported (0x%x)\n",
pci_name(pdev), (int) tmp8);
rc = -EIO;
goto err_out_regions;
if (board_id == vt6420) {
pci_read_config_byte(pdev, SATA_PATA_SHARING, &tmp8);
if (tmp8 & SATA_2DEV) {
printk(KERN_ERR DRV_NAME "(%s): SATA master/slave not supported (0x%x)\n",
pci_name(pdev), (int) tmp8);
rc = -EIO;
goto err_out_regions;
}
bar_sizes = &svia_bar_sizes[0];
} else {
bar_sizes = &vt6421_bar_sizes[0];
}
for (i = 0; i < ARRAY_SIZE(svia_bar_sizes); i++)
if ((pci_resource_start(pdev, i) == 0) ||
(pci_resource_len(pdev, i) < svia_bar_sizes[i])) {
(pci_resource_len(pdev, i) < bar_sizes[i])) {
printk(KERN_ERR DRV_NAME "(%s): invalid PCI BAR %u (sz 0x%lx, val 0x%lx)\n",
pci_name(pdev), i,
pci_resource_start(pdev, i),
......@@ -209,8 +341,11 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc)
goto err_out_regions;
ppi = &svia_port_info;
probe_ent = ata_pci_init_native_mode(pdev, &ppi);
if (board_id == vt6420)
probe_ent = vt6420_init_probe_ent(pdev);
else
probe_ent = vt6421_init_probe_ent(pdev);
if (!probe_ent) {
printk(KERN_ERR DRV_NAME "(%s): out of memory\n",
pci_name(pdev));
......@@ -218,42 +353,7 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_regions;
}
probe_ent->port[0].scr_addr =
svia_scr_addr(pci_resource_start(pdev, 5), 0);
probe_ent->port[1].scr_addr =
svia_scr_addr(pci_resource_start(pdev, 5), 1);
pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &tmp8);
printk(KERN_INFO DRV_NAME "(%s): routed to hard irq line %d\n",
pci_name(pdev),
(int) (tmp8 & 0xf0) == 0xf0 ? 0 : tmp8 & 0x0f);
/* make sure SATA channels are enabled */
pci_read_config_byte(pdev, SATA_CHAN_ENAB, &tmp8);
if ((tmp8 & ENAB_ALL) != ENAB_ALL) {
printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channels (0x%x)\n",
pci_name(pdev), (int) tmp8);
tmp8 |= ENAB_ALL;
pci_write_config_byte(pdev, SATA_CHAN_ENAB, tmp8);
}
/* make sure interrupts for each channel sent to us */
pci_read_config_byte(pdev, SATA_INT_GATE, &tmp8);
if ((tmp8 & INT_GATE_ALL) != INT_GATE_ALL) {
printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channel interrupts (0x%x)\n",
pci_name(pdev), (int) tmp8);
tmp8 |= INT_GATE_ALL;
pci_write_config_byte(pdev, SATA_INT_GATE, tmp8);
}
/* make sure native mode is enabled */
pci_read_config_byte(pdev, SATA_NATIVE_MODE, &tmp8);
if ((tmp8 & NATIVE_MODE_ALL) != NATIVE_MODE_ALL) {
printk(KERN_DEBUG DRV_NAME "(%s): enabling SATA channel native mode (0x%x)\n",
pci_name(pdev), (int) tmp8);
tmp8 |= NATIVE_MODE_ALL;
pci_write_config_byte(pdev, SATA_NATIVE_MODE, tmp8);
}
svia_configure(pdev);
pci_set_master(pdev);
......@@ -266,7 +366,8 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
err_out_regions:
pci_release_regions(pdev);
err_out:
pci_disable_device(pdev);
if (!pci_dev_busy)
pci_disable_device(pdev);
return rc;
}
......
......@@ -217,6 +217,8 @@ static struct ata_port_operations vsc_sata_ops = {
.phy_reset = sata_phy_reset,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
.bmdma_stop = ata_bmdma_stop,
.bmdma_status = ata_bmdma_status,
.qc_prep = ata_qc_prep,
.qc_issue = ata_qc_issue_prot,
.eng_timeout = ata_eng_timeout,
......@@ -255,6 +257,7 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
static int printed_version;
struct ata_probe_ent *probe_ent = NULL;
unsigned long base;
int pci_dev_busy = 0;
void *mmio_base;
int rc;
......@@ -274,8 +277,10 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
}
rc = pci_request_regions(pdev, DRV_NAME);
if (rc)
if (rc) {
pci_dev_busy = 1;
goto err_out;
}
/*
* Use 32 bit DMA mask, because 64 bit address support is poor.
......@@ -352,7 +357,8 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d
err_out_regions:
pci_release_regions(pdev);
err_out:
pci_disable_device(pdev);
if (!pci_dev_busy)
pci_disable_device(pdev);
return rc;
}
......
......@@ -303,10 +303,10 @@ static int do_getlk(struct file *filp, int cmd, struct file_lock *fl)
status = NFS_PROTO(inode)->lock(filp, cmd, fl);
else {
struct file_lock *cfl = posix_test_lock(filp, fl);
if (cfl != NULL) {
fl->fl_type = F_UNLCK;
if (cfl != NULL)
memcpy(fl, cfl, sizeof(*fl));
fl->fl_type = F_UNLCK;
}
}
unlock_kernel();
return status;
......
......@@ -54,7 +54,7 @@ struct agp_kern_info {
struct pci_dev *device;
enum chipset_type chipset;
unsigned long mode;
off_t aper_base;
unsigned long aper_base;
size_t aper_size;
int max_memory; /* In pages */
int current_memory;
......
......@@ -64,7 +64,7 @@ typedef struct _agp_info {
struct agp_version version; /* version of the driver */
__u32 bridge_id; /* bridge vendor/device */
__u32 agp_mode; /* mode info of bridge */
off_t aper_base; /* base of aperture */
unsigned long aper_base;/* base of aperture */
size_t aper_size; /* size of aperture */
size_t pg_total; /* max pages (swap + system) */
size_t pg_system; /* max pages (system) */
......@@ -118,7 +118,7 @@ struct agp_info {
struct agp_version version; /* version of the driver */
u32 bridge_id; /* bridge vendor/device */
u32 agp_mode; /* mode info of bridge */
off_t aper_base; /* base of aperture */
unsigned long aper_base;/* base of aperture */
size_t aper_size; /* size of aperture */
size_t pg_total; /* max pages (swap + system) */
size_t pg_system; /* max pages (system) */
......
......@@ -334,6 +334,8 @@ struct ata_port_operations {
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);
......@@ -360,6 +362,9 @@ struct ata_port_operations {
void (*port_stop) (struct ata_port *ap);
void (*host_stop) (struct ata_host_set *host_set);
void (*bmdma_stop) (struct ata_port *ap);
u8 (*bmdma_status) (struct ata_port *ap);
};
struct ata_port_info {
......@@ -400,6 +405,8 @@ extern void ata_tf_from_fis(u8 *fis, struct ata_taskfile *tf);
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);
......@@ -415,6 +422,8 @@ extern void ata_dev_id_string(u16 *id, unsigned char *s,
unsigned int ofs, unsigned int len);
extern void ata_bmdma_setup (struct ata_queued_cmd *qc);
extern void ata_bmdma_start (struct ata_queued_cmd *qc);
extern void ata_bmdma_stop(struct ata_port *ap);
extern u8 ata_bmdma_status(struct ata_port *ap);
extern void ata_bmdma_irq_clear(struct ata_port *ap);
extern void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat);
extern void ata_eng_timeout(struct ata_port *ap);
......@@ -452,26 +461,11 @@ static inline unsigned int ata_dev_present(struct ata_device *dev)
(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)
{
ata_altstatus(ap);
......@@ -595,46 +589,6 @@ static inline unsigned int sata_dev_present(struct ata_port *ap)
return ((scr_read(ap, SCR_STATUS) & 0xf) == 0x3) ? 1 : 0;
}
static inline void ata_bmdma_stop(struct ata_port *ap)
{
if (ap->flags & ATA_FLAG_MMIO) {
void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
/* clear start/stop bit */
writeb(readb(mmio + ATA_DMA_CMD) & ~ATA_DMA_START,
mmio + ATA_DMA_CMD);
} else {
/* clear start/stop bit */
outb(inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD) & ~ATA_DMA_START,
ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
}
/* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
ata_altstatus(ap); /* dummy read */
}
static inline void ata_bmdma_ack_irq(struct ata_port *ap)
{
if (ap->flags & ATA_FLAG_MMIO) {
void __iomem *mmio = ((void __iomem *) ap->ioaddr.bmdma_addr) + ATA_DMA_STATUS;
writeb(readb(mmio), mmio);
} else {
unsigned long addr = ap->ioaddr.bmdma_addr + ATA_DMA_STATUS;
outb(inb(addr), addr);
}
}
static inline u8 ata_bmdma_status(struct ata_port *ap)
{
u8 host_stat;
if (ap->flags & ATA_FLAG_MMIO) {
void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
host_stat = readb(mmio + ATA_DMA_STATUS);
} else
host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
return host_stat;
}
static inline int ata_try_flush_cache(struct ata_device *dev)
{
return ata_id_wcache_enabled(dev->id) ||
......
......@@ -258,6 +258,18 @@ static void drop_key_refs(union futex_key *key)
}
}
static inline int get_futex_value_locked(int *dest, int __user *from)
{
int ret;
inc_preempt_count();
ret = __copy_from_user_inatomic(dest, from, sizeof(int));
dec_preempt_count();
preempt_check_resched();
return ret ? -EFAULT : 0;
}
/*
* The hash bucket lock must be held when this is called.
* Afterwards, the futex_q must not be accessed.
......@@ -329,6 +341,7 @@ static int futex_requeue(unsigned long uaddr1, unsigned long uaddr2,
int ret, drop_count = 0;
unsigned int nqueued;
retry:
down_read(&current->mm->mmap_sem);
ret = get_futex_key(uaddr1, &key1);
......@@ -355,9 +368,20 @@ static int futex_requeue(unsigned long uaddr1, unsigned long uaddr2,
before *uaddr1. */
smp_mb();
if (get_user(curval, (int __user *)uaddr1) != 0) {
ret = -EFAULT;
goto out;
ret = get_futex_value_locked(&curval, (int __user *)uaddr1);
if (unlikely(ret)) {
/* If we would have faulted, release mmap_sem, fault
* it in and start all over again.
*/
up_read(&current->mm->mmap_sem);
ret = get_user(curval, (int __user *)uaddr1);
if (!ret)
goto retry;
return ret;
}
if (curval != *valp) {
ret = -EAGAIN;
......@@ -480,6 +504,7 @@ static int futex_wait(unsigned long uaddr, int val, unsigned long time)
int ret, curval;
struct futex_q q;
retry:
down_read(&current->mm->mmap_sem);
ret = get_futex_key(uaddr, &q.key);
......@@ -508,9 +533,23 @@ static int futex_wait(unsigned long uaddr, int val, unsigned long time)
* We hold the mmap semaphore, so the mapping cannot have changed
* since we looked it up in get_futex_key.
*/
if (get_user(curval, (int __user *)uaddr) != 0) {
ret = -EFAULT;
goto out_unqueue;
ret = get_futex_value_locked(&curval, (int __user *)uaddr);
if (unlikely(ret)) {
/* If we would have faulted, release mmap_sem, fault it in and
* start all over again.
*/
up_read(&current->mm->mmap_sem);
if (!unqueue_me(&q)) /* There's a chance we got woken already */
return 0;
ret = get_user(curval, (int __user *)uaddr);
if (!ret)
goto retry;
return ret;
}
if (curval != val) {
ret = -EWOULDBLOCK;
......
......@@ -524,9 +524,13 @@ asmlinkage long sys_get_mempolicy(int __user *policy,
} else
pval = pol->policy;
err = -EFAULT;
if (vma) {
up_read(&current->mm->mmap_sem);
vma = NULL;
}
if (policy && put_user(pval, policy))
goto out;
return -EFAULT;
err = 0;
if (nmask) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment